personal web client for Bluesky
typescript solidjs bluesky atcute

refactor: massive atcute migration

mary.my.id 55af475c 15155286

verified
Changed files
+675 -805
src
api
components
lib
aglais-bookmarks
atproto
bsky
preferences
states
views
+7 -4
package.json
··· 8 8 "fmt": "prettier --cache --write ." 9 9 }, 10 10 "dependencies": { 11 - "@atcute/bluemoji": "^2.0.0", 12 - "@atcute/bluesky": "^2.1.1", 11 + "@atcute/atproto": "^3.1.0", 12 + "@atcute/bluemoji": "^3.1.0", 13 + "@atcute/bluesky": "^3.1.0", 13 14 "@atcute/bluesky-richtext-parser": "^1.0.7", 14 15 "@atcute/bluesky-richtext-segmenter": "^2.0.3", 15 16 "@atcute/bluesky-search-parser": "^0.1.0", 16 17 "@atcute/cbor": "^2.2.4", 17 18 "@atcute/cid": "^2.2.3", 18 - "@atcute/client": "^3.1.0", 19 + "@atcute/client": "^4.0.3", 20 + "@atcute/lexicons": "^1.0.4", 19 21 "@atcute/oauth-browser-client": "^1.0.25", 20 22 "@atcute/tid": "^1.0.2", 21 23 "@atlaskit/pragmatic-drag-and-drop": "1.6.0", 22 24 "@atlaskit/pragmatic-drag-and-drop-hitbox": "1.0.3", 23 25 "@floating-ui/dom": "^1.7.0", 24 26 "@floating-ui/utils": "^0.2.9", 27 + "@kelinci/basa-lexicons": "^1.0.0", 25 28 "@mary/array-fns": "jsr:^0.1.4", 26 29 "@mary/async-iterator-fns": "jsr:^0.1.1", 27 30 "@mary/batch-fetch": "jsr:^0.1.0", ··· 52 55 "vite": "^6.3.5", 53 56 "vite-plugin-pwa": "0.21.0", 54 57 "vite-plugin-solid": "^2.11.6", 55 - "wrangler": "^4.17.0" 58 + "wrangler": "^4.18.0" 56 59 }, 57 60 "pnpm": { 58 61 "patchedDependencies": {
+112 -112
pnpm-lock.yaml
··· 30 30 31 31 .: 32 32 dependencies: 33 + '@atcute/atproto': 34 + specifier: ^3.1.0 35 + version: 3.1.0 33 36 '@atcute/bluemoji': 34 - specifier: ^2.0.0 35 - version: 2.0.0(@atcute/bluesky@2.1.1(@atcute/client@3.1.0))(@atcute/client@3.1.0) 37 + specifier: ^3.1.0 38 + version: 3.1.0 36 39 '@atcute/bluesky': 37 - specifier: ^2.1.1 38 - version: 2.1.1(@atcute/client@3.1.0) 40 + specifier: ^3.1.0 41 + version: 3.1.0 39 42 '@atcute/bluesky-richtext-parser': 40 43 specifier: ^1.0.7 41 44 version: 1.0.7 ··· 52 55 specifier: ^2.2.3 53 56 version: 2.2.3 54 57 '@atcute/client': 55 - specifier: ^3.1.0 56 - version: 3.1.0 58 + specifier: ^4.0.3 59 + version: 4.0.3 60 + '@atcute/lexicons': 61 + specifier: ^1.0.4 62 + version: 1.0.4 57 63 '@atcute/oauth-browser-client': 58 64 specifier: ^1.0.25 59 65 version: 1.0.25 ··· 72 78 '@floating-ui/utils': 73 79 specifier: ^0.2.9 74 80 version: 0.2.9(patch_hash=1cf283fbaa686f96f7b3029bbc0955bff698af6f4a75ba6c276ad1a7a7c40aea) 81 + '@kelinci/basa-lexicons': 82 + specifier: ^1.0.0 83 + version: 1.0.0 75 84 '@mary/array-fns': 76 85 specifier: jsr:^0.1.4 77 86 version: '@jsr/mary__array-fns@0.1.4' ··· 129 138 version: 0.1.15 130 139 autoprefixer: 131 140 specifier: ^10.4.21 132 - version: 10.4.21(postcss@8.5.3) 141 + version: 10.4.21(postcss@8.5.4) 133 142 babel-plugin-transform-typescript-const-enums: 134 143 specifier: ^0.1.0 135 144 version: 0.1.0(@babel/core@7.27.3) ··· 158 167 specifier: ^2.11.6 159 168 version: 2.11.6(solid-js@1.9.7(patch_hash=9cf3f9930aa2f8d4e60502a75153adf9468eb53b42f69e86cac05dfaea3f82e7))(vite@6.3.5(jiti@1.21.7)(terser@5.40.0)(yaml@2.8.0)) 160 169 wrangler: 161 - specifier: ^4.17.0 162 - version: 4.17.0 170 + specifier: ^4.18.0 171 + version: 4.18.0 163 172 164 173 packages: 165 174 ··· 177 186 peerDependencies: 178 187 ajv: '>=8' 179 188 180 - '@atcute/atproto@3.0.3': 181 - resolution: {integrity: sha512-pJOTvviq816o0uAG3JquVNmCPph67p30+0UU4XDoJIChPAwtXMT5SW3sjNpWYh3sfwayhSCiBRBOAgKsUHR+xg==} 189 + '@atcute/atproto@3.1.0': 190 + resolution: {integrity: sha512-aJbDsY7FcIh8APWKAimBtshPwqoRE056tc0UV6vw4TW4e3nYaHedoJmKhlh/k8KQWxyw64MQThNGMaC89HNoTg==} 182 191 183 - '@atcute/bluemoji@2.0.0': 184 - resolution: {integrity: sha512-tgcsW4H50oWo6uHMkUVU2IgObfX63mYp/qxWfoLkKPFWbwz68SiwedaCY/E+Cw8anWGF0urFjDemmga7B5Z0QA==} 185 - peerDependencies: 186 - '@atcute/bluesky': ^2.0.0 187 - '@atcute/client': ^3.0.0 192 + '@atcute/bluemoji@3.1.0': 193 + resolution: {integrity: sha512-8EfcEDrXlStvu57WVcGSeDWfbEDKTjfI43rk+oohe2sdYU113ObTe8Pv1vW0DRfOYcQqR4+eF2SbpvXE6//24g==} 188 194 189 195 '@atcute/bluesky-richtext-parser@1.0.7': 190 196 resolution: {integrity: sha512-nOvU699OXiGMbyswao7JJnY0C9WkwE7PVC/m5WWt0UN9fsXSOor9IZWw+v9SATp+94BTJoG38XyUomUaJnoQRA==} ··· 195 201 '@atcute/bluesky-search-parser@0.1.0': 196 202 resolution: {integrity: sha512-bTClwD9VGwaECOyWe1mf8V6t+7/77e3tiUHTE6CSrHXOJ/yM8N2xbn+dIi2ki2JLHvgvBN9wsWpFLykgfWhBaw==} 197 203 198 - '@atcute/bluesky@2.1.1': 199 - resolution: {integrity: sha512-wEZfFW58J6yC1SqHcVJOn4qbHENTTzjeCEWthRT5HvKovADLqk54HSMSAuXDMBUbintSTBr0khQNZQ3ZdgzDdQ==} 200 - peerDependencies: 201 - '@atcute/client': ^3.0.0 202 - 203 - '@atcute/bluesky@3.0.4': 204 - resolution: {integrity: sha512-GiadvV6HVkBKRGMuWU3EjMq+EfOEf7YJXArthu7XlQIXVYuJDwVqGldxAlPgUkOrAW3PMc/fANrFhatbQRR4cg==} 204 + '@atcute/bluesky@3.1.0': 205 + resolution: {integrity: sha512-i5ABWnRpw+YsMyUz9jkkrbN0m3Fz8qLy4nIMPs4IoSKgO/UjmZFvfIkabXUOUHcnHPgph2yViXA1buzTR0RNWQ==} 205 206 206 207 '@atcute/cbor@2.2.4': 207 208 resolution: {integrity: sha512-8Y/OTM8zs5VInOCjfx4f9Idiiz7ygM/FkfWv/HW3/ZUsXczn1xk7GzTBbm4P5crn4C5luwDGpO7FwClMOERrow==} 208 209 209 210 '@atcute/cid@2.2.3': 210 211 resolution: {integrity: sha512-WEzNSL1EuCVtCQDFYEBIm4dEP6PcMEwi8IYUVIWvT77eO5EjY58F63z5T4qMABxSBM0+L4kqMxypdL1Fzf6LZw==} 211 - 212 - '@atcute/client@3.1.0': 213 - resolution: {integrity: sha512-+rQPsHXSf0DUm8XoHoaH7Y2E8tIpbsW84djyPj7dqAyrFIjvGuJ1X1DvMufwbTIcmLerdy+dzl34iZcz/h3Vhg==} 214 212 215 213 '@atcute/client@4.0.3': 216 214 resolution: {integrity: sha512-RIOZWFVLca/HiPAAUDqQPOdOreCxTbL5cb+WUf5yqQOKIu5yEAP3eksinmlLmgIrlr5qVOE7brazUUzaskFCfw==} ··· 751 749 workerd: 752 750 optional: true 753 751 754 - '@cloudflare/workerd-darwin-64@1.20250523.0': 755 - resolution: {integrity: sha512-/K7vKkPDx9idJ7hJtqYXYsKkHX9XQ6awyDyBZ4RwbaQ/o3fyS/tgHaej2rUO6zkb7CfUxiaeAB7Z6i7KltMY5Q==} 752 + '@cloudflare/workerd-darwin-64@1.20250525.0': 753 + resolution: {integrity: sha512-L5l+7sSJJT2+riR5rS3Q3PKNNySPjWfRIeaNGMVRi1dPO6QPi4lwuxfRUFNoeUdilZJUVPfSZvTtj9RedsKznQ==} 756 754 engines: {node: '>=16'} 757 755 cpu: [x64] 758 756 os: [darwin] 759 757 760 - '@cloudflare/workerd-darwin-arm64@1.20250523.0': 761 - resolution: {integrity: sha512-tVQqStt245KzkrCT6DBXoMNHaJgh/8hQy3fsG+4gHfqw/JdKEgXigkc9hWdC6BoS5DiGK+dGVJo2MnWHFC7XlQ==} 758 + '@cloudflare/workerd-darwin-arm64@1.20250525.0': 759 + resolution: {integrity: sha512-Y3IbIdrF/vJWh/WBvshwcSyUh175VAiLRW7963S1dXChrZ1N5wuKGQm9xY69cIGVtitpMJWWW3jLq7J/Xxwm0Q==} 762 760 engines: {node: '>=16'} 763 761 cpu: [arm64] 764 762 os: [darwin] 765 763 766 - '@cloudflare/workerd-linux-64@1.20250523.0': 767 - resolution: {integrity: sha512-PCPWBlwiKr9Es2TP93JVygXRPwx+AkygUMV2gFOPerVrdXUd13A4dJ68Qjpmh3O0xqmVIRV6PSogM3wNvwnw5Q==} 764 + '@cloudflare/workerd-linux-64@1.20250525.0': 765 + resolution: {integrity: sha512-KSyQPAby+c6cpENoO0ayCQlY6QIh28l/+QID7VC1SLXfiNHy+hPNsH1vVBTST6CilHVAQSsy9tCZ9O9XECB8yg==} 768 766 engines: {node: '>=16'} 769 767 cpu: [x64] 770 768 os: [linux] 771 769 772 - '@cloudflare/workerd-linux-arm64@1.20250523.0': 773 - resolution: {integrity: sha512-uKa/L9W1AzT+yE0wNxFZPlMXms5xmGaaOmTAK0wuLPW6qmKj1zyBidjHqQXVZ+eK/fLy3CNeyB9EBtR0/8FH7A==} 770 + '@cloudflare/workerd-linux-arm64@1.20250525.0': 771 + resolution: {integrity: sha512-Nt0FUxS2kQhJUea4hMCNPaetkrAFDhPnNX/ntwcqVlGgnGt75iaAhupWJbU0GB+gIWlKeuClUUnDZqKbicoKyg==} 774 772 engines: {node: '>=16'} 775 773 cpu: [arm64] 776 774 os: [linux] 777 775 778 - '@cloudflare/workerd-windows-64@1.20250523.0': 779 - resolution: {integrity: sha512-H5ggClWrskRs7pj2Fd+iJpjFMrh7DZqAfhJT3IloTW85lCEY2+y/yfXEGyDsc0UTLuTS0znldcUrVCRjSiSOkw==} 776 + '@cloudflare/workerd-windows-64@1.20250525.0': 777 + resolution: {integrity: sha512-mwTj+9f3uIa4NEXR1cOa82PjLa6dbrb3J+KCVJFYIaq7e63VxEzOchCXS4tublT2pmOhmFqkgBMXrxozxNkR2Q==} 780 778 engines: {node: '>=16'} 781 779 cpu: [x64] 782 780 os: [win32] ··· 1262 1260 '@jsr/mary__exif-rm@0.2.2': 1263 1261 resolution: {integrity: sha512-+ZpLaC+1CyqWhH608Sqd6/yTG0pOlokn2tCXha7s1SMQ+GLKo4Nn/PskTeeP9Pt+6gNYSu6ednoSlRvXb2ZGxg==, tarball: https://npm.jsr.io/~/11/@jsr/mary__exif-rm/0.2.2.tgz} 1264 1262 1263 + '@kelinci/basa-lexicons@1.0.0': 1264 + resolution: {integrity: sha512-QND0ktwpGySoHhqRUrLZ3YybyHnOkV6mGCLn75yJWl9PpKIMh/gmAyvXIo1ZuzSHu4v6xcSyi3A78QoH4MhTGw==} 1265 + 1265 1266 '@nodelib/fs.scandir@2.1.5': 1266 1267 resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} 1267 1268 engines: {node: '>= 8'} ··· 1610 1611 resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} 1611 1612 engines: {node: '>=8'} 1612 1613 1613 - browserslist@4.24.5: 1614 - resolution: {integrity: sha512-FDToo4Wo82hIdgc1CQ+NQD0hEhmpPjrZ3hiUgwgOG6IuTdlpr8jdjyG24P6cNP1yJpTLzS5OcGgSw0xmDU1/Tw==} 1614 + browserslist@4.25.0: 1615 + resolution: {integrity: sha512-PJ8gYKeS5e/whHBh8xrwYK+dAvEj7JXtz6uTucnMRB8OiGTsKccFekoRrjajPBHV8oOY+2tI4uxeceSimKwMFA==} 1615 1616 engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} 1616 1617 hasBin: true 1617 1618 ··· 1622 1623 resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} 1623 1624 engines: {node: '>= 6'} 1624 1625 1625 - caniuse-lite@1.0.30001718: 1626 - resolution: {integrity: sha512-AflseV1ahcSunK53NfEs9gFWgOEmzr0f+kaMFA4xiLZlr9Hzt7HxcSpIFcnNCUkz6R6dWKa54rUz3HUmI3nVcw==} 1626 + caniuse-lite@1.0.30001720: 1627 + resolution: {integrity: sha512-Ec/2yV2nNPwb4DnTANEV99ZWwm3ZWfdlfkQbWSDDt+PsXEVYwlhPH8tdMaPunYTKKmz7AnHi2oNEi1GcmKCD8g==} 1627 1628 1628 1629 chalk@4.1.2: 1629 1630 resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} ··· 1727 1728 engines: {node: '>=0.10.0'} 1728 1729 hasBin: true 1729 1730 1730 - electron-to-chromium@1.5.159: 1731 - resolution: {integrity: sha512-CEvHptWAMV5p6GJ0Lq8aheyvVbfzVrv5mmidu1D3pidoVNkB3tTBsTMVtPJ+rzRK5oV229mCLz9Zj/hNvU8GBA==} 1731 + electron-to-chromium@1.5.161: 1732 + resolution: {integrity: sha512-hwtetwfKNZo/UlwHIVBlKZVdy7o8bIZxxKs0Mv/ROPiQQQmDgdm5a+KvKtBsxM8ZjFzTaCeLoodZ8jiBE3o9rA==} 1732 1733 1733 1734 emoji-regex@8.0.0: 1734 1735 resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} ··· 2020 2021 engines: {node: '>=10.0.0'} 2021 2022 hasBin: true 2022 2023 2023 - miniflare@4.20250523.0: 2024 - resolution: {integrity: sha512-g4F1AC5xi66rB2eQNo2Fx7EffaXhMdgUSRl/ivgb4LMALMpxghG98oC4twqVwDLWIFSVFjtL1YEuYrPO8044mg==} 2024 + miniflare@4.20250525.0: 2025 + resolution: {integrity: sha512-F5XRDn9WqxUaHphUT8qwy5WXC/3UwbBRJTdjjP5uwHX82vypxIlHNyHziZnplPLhQa1kbSdIY7wfuP1XJyyYZw==} 2025 2026 engines: {node: '>=18.0.0'} 2026 2027 hasBin: true 2027 2028 ··· 2168 2169 postcss-value-parser@4.2.0: 2169 2170 resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} 2170 2171 2171 - postcss@8.5.3: 2172 - resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==} 2172 + postcss@8.5.4: 2173 + resolution: {integrity: sha512-QSa9EBe+uwlGTFmHsPKokv3B/oEMQZxfqW0QqNCyhpa6mB1afzulwn8hihglqAb2pOw+BJgNlmXQ8la2VeHB7w==} 2173 2174 engines: {node: ^10 || ^12 || >=14} 2174 2175 2175 2176 prettier-plugin-tailwindcss@0.6.11: ··· 2661 2662 workbox-window@7.3.0: 2662 2663 resolution: {integrity: sha512-qW8PDy16OV1UBaUNGlTVcepzrlzyzNW/ZJvFQQs2j2TzGsg6IKjcpZC1RSquqQnTOafl5pCj5bGfAHlCjOOjdA==} 2663 2664 2664 - workerd@1.20250523.0: 2665 - resolution: {integrity: sha512-OClsq9ZzZZNdkY8/JTBjf+/A6F1q/SOn3/RQWCR0kDoclxecHS6Nq80jY6NP0ubJBKnqrUggA9WOWBgwWWOGUA==} 2665 + workerd@1.20250525.0: 2666 + resolution: {integrity: sha512-SXJgLREy/Aqw2J71Oah0Pbu+SShbqbTExjVQyRBTM1r7MG7fS5NUlknhnt6sikjA/t4cO09Bi8OJqHdTkrcnYQ==} 2666 2667 engines: {node: '>=16'} 2667 2668 hasBin: true 2668 2669 2669 - wrangler@4.17.0: 2670 - resolution: {integrity: sha512-FIOriw2Z7aNALAtnt4hTojDuU44n8pGJl62id0ig0s45Mej/Clg07vpmz+QCLTT7huiaSSyA1wthYOwtp0+K6A==} 2670 + wrangler@4.18.0: 2671 + resolution: {integrity: sha512-/ng0KI9io97SNsBU1rheADBLLTE5Djybgsi4gXuvH1RBKJGpyj1xWvZ2fuWu8vAonit3EiZkwtERTm6kESHP3A==} 2671 2672 engines: {node: '>=18.0.0'} 2672 2673 hasBin: true 2673 2674 peerDependencies: 2674 - '@cloudflare/workers-types': ^4.20250523.0 2675 + '@cloudflare/workers-types': ^4.20250525.0 2675 2676 peerDependenciesMeta: 2676 2677 '@cloudflare/workers-types': 2677 2678 optional: true ··· 2729 2730 jsonpointer: 5.0.1 2730 2731 leven: 3.1.0 2731 2732 2732 - '@atcute/atproto@3.0.3': 2733 + '@atcute/atproto@3.1.0': 2733 2734 dependencies: 2734 2735 '@atcute/lexicons': 1.0.4 2735 2736 2736 - '@atcute/bluemoji@2.0.0(@atcute/bluesky@2.1.1(@atcute/client@3.1.0))(@atcute/client@3.1.0)': 2737 + '@atcute/bluemoji@3.1.0': 2737 2738 dependencies: 2738 - '@atcute/bluesky': 2.1.1(@atcute/client@3.1.0) 2739 - '@atcute/client': 3.1.0 2739 + '@atcute/atproto': 3.1.0 2740 + '@atcute/bluesky': 3.1.0 2741 + '@atcute/lexicons': 1.0.4 2740 2742 2741 2743 '@atcute/bluesky-richtext-parser@1.0.7': {} 2742 2744 2743 2745 '@atcute/bluesky-richtext-segmenter@2.0.3': 2744 2746 dependencies: 2745 - '@atcute/bluesky': 3.0.4 2747 + '@atcute/bluesky': 3.1.0 2746 2748 '@atcute/lexicons': 1.0.4 2747 2749 2748 2750 '@atcute/bluesky-search-parser@0.1.0': {} 2749 2751 2750 - '@atcute/bluesky@2.1.1(@atcute/client@3.1.0)': 2751 - dependencies: 2752 - '@atcute/client': 3.1.0 2753 - 2754 - '@atcute/bluesky@3.0.4': 2752 + '@atcute/bluesky@3.1.0': 2755 2753 dependencies: 2756 - '@atcute/atproto': 3.0.3 2754 + '@atcute/atproto': 3.1.0 2757 2755 '@atcute/lexicons': 1.0.4 2758 2756 2759 2757 '@atcute/cbor@2.2.4': ··· 2766 2764 dependencies: 2767 2765 '@atcute/multibase': 1.1.4 2768 2766 '@atcute/uint8array': 1.0.3 2769 - 2770 - '@atcute/client@3.1.0': {} 2771 2767 2772 2768 '@atcute/client@4.0.3': 2773 2769 dependencies: ··· 2855 2851 dependencies: 2856 2852 '@babel/compat-data': 7.27.3 2857 2853 '@babel/helper-validator-option': 7.27.1 2858 - browserslist: 4.24.5 2854 + browserslist: 4.25.0 2859 2855 lru-cache: 5.1.1 2860 2856 semver: 6.3.1 2861 2857 ··· 3463 3459 dependencies: 3464 3460 mime: 3.0.0 3465 3461 3466 - '@cloudflare/unenv-preset@2.3.2(unenv@2.0.0-rc.17)(workerd@1.20250523.0)': 3462 + '@cloudflare/unenv-preset@2.3.2(unenv@2.0.0-rc.17)(workerd@1.20250525.0)': 3467 3463 dependencies: 3468 3464 unenv: 2.0.0-rc.17 3469 3465 optionalDependencies: 3470 - workerd: 1.20250523.0 3466 + workerd: 1.20250525.0 3471 3467 3472 - '@cloudflare/workerd-darwin-64@1.20250523.0': 3468 + '@cloudflare/workerd-darwin-64@1.20250525.0': 3473 3469 optional: true 3474 3470 3475 - '@cloudflare/workerd-darwin-arm64@1.20250523.0': 3471 + '@cloudflare/workerd-darwin-arm64@1.20250525.0': 3476 3472 optional: true 3477 3473 3478 - '@cloudflare/workerd-linux-64@1.20250523.0': 3474 + '@cloudflare/workerd-linux-64@1.20250525.0': 3479 3475 optional: true 3480 3476 3481 - '@cloudflare/workerd-linux-arm64@1.20250523.0': 3477 + '@cloudflare/workerd-linux-arm64@1.20250525.0': 3482 3478 optional: true 3483 3479 3484 - '@cloudflare/workerd-windows-64@1.20250523.0': 3480 + '@cloudflare/workerd-windows-64@1.20250525.0': 3485 3481 optional: true 3486 3482 3487 3483 '@cspotcode/source-map-support@0.8.1': ··· 3788 3784 3789 3785 '@jsr/mary__exif-rm@0.2.2': {} 3790 3786 3787 + '@kelinci/basa-lexicons@1.0.0': 3788 + dependencies: 3789 + '@atcute/lexicons': 1.0.4 3790 + 3791 3791 '@nodelib/fs.scandir@2.1.5': 3792 3792 dependencies: 3793 3793 '@nodelib/fs.stat': 2.0.5 ··· 4019 4019 4020 4020 at-least-node@1.0.0: {} 4021 4021 4022 - autoprefixer@10.4.21(postcss@8.5.3): 4022 + autoprefixer@10.4.21(postcss@8.5.4): 4023 4023 dependencies: 4024 - browserslist: 4.24.5 4025 - caniuse-lite: 1.0.30001718 4024 + browserslist: 4.25.0 4025 + caniuse-lite: 1.0.30001720 4026 4026 fraction.js: 4.3.7 4027 4027 normalize-range: 0.1.2 4028 4028 picocolors: 1.1.1 4029 - postcss: 8.5.3 4029 + postcss: 8.5.4 4030 4030 postcss-value-parser: 4.2.0 4031 4031 4032 4032 babel-plugin-jsx-dom-expressions@0.39.8(@babel/core@7.27.3): ··· 4095 4095 dependencies: 4096 4096 fill-range: 7.1.1 4097 4097 4098 - browserslist@4.24.5: 4098 + browserslist@4.25.0: 4099 4099 dependencies: 4100 - caniuse-lite: 1.0.30001718 4101 - electron-to-chromium: 1.5.159 4100 + caniuse-lite: 1.0.30001720 4101 + electron-to-chromium: 1.5.161 4102 4102 node-releases: 2.0.19 4103 - update-browserslist-db: 1.1.3(browserslist@4.24.5) 4103 + update-browserslist-db: 1.1.3(browserslist@4.25.0) 4104 4104 4105 4105 buffer-from@1.1.2: {} 4106 4106 4107 4107 camelcase-css@2.0.1: {} 4108 4108 4109 - caniuse-lite@1.0.30001718: {} 4109 + caniuse-lite@1.0.30001720: {} 4110 4110 4111 4111 chalk@4.1.2: 4112 4112 dependencies: ··· 4157 4157 4158 4158 core-js-compat@3.42.0: 4159 4159 dependencies: 4160 - browserslist: 4.24.5 4160 + browserslist: 4.25.0 4161 4161 4162 4162 cross-spawn@7.0.6: 4163 4163 dependencies: ··· 4193 4193 dependencies: 4194 4194 jake: 10.9.2 4195 4195 4196 - electron-to-chromium@1.5.159: {} 4196 + electron-to-chromium@1.5.161: {} 4197 4197 4198 4198 emoji-regex@8.0.0: {} 4199 4199 ··· 4478 4478 4479 4479 mime@3.0.0: {} 4480 4480 4481 - miniflare@4.20250523.0: 4481 + miniflare@4.20250525.0: 4482 4482 dependencies: 4483 4483 '@cspotcode/source-map-support': 0.8.1 4484 4484 acorn: 8.14.0 ··· 4488 4488 sharp: 0.33.5 4489 4489 stoppable: 1.1.0 4490 4490 undici: 5.29.0 4491 - workerd: 1.20250523.0 4491 + workerd: 1.20250525.0 4492 4492 ws: 8.18.0 4493 4493 youch: 3.3.4 4494 4494 zod: 3.22.3 ··· 4571 4571 4572 4572 pirates@4.0.7: {} 4573 4573 4574 - postcss-import@15.1.0(postcss@8.5.3): 4574 + postcss-import@15.1.0(postcss@8.5.4): 4575 4575 dependencies: 4576 - postcss: 8.5.3 4576 + postcss: 8.5.4 4577 4577 postcss-value-parser: 4.2.0 4578 4578 read-cache: 1.0.0 4579 4579 resolve: 1.22.10 4580 4580 4581 - postcss-js@4.0.1(postcss@8.5.3): 4581 + postcss-js@4.0.1(postcss@8.5.4): 4582 4582 dependencies: 4583 4583 camelcase-css: 2.0.1 4584 - postcss: 8.5.3 4584 + postcss: 8.5.4 4585 4585 4586 - postcss-load-config@4.0.2(postcss@8.5.3): 4586 + postcss-load-config@4.0.2(postcss@8.5.4): 4587 4587 dependencies: 4588 4588 lilconfig: 3.1.3 4589 4589 yaml: 2.8.0 4590 4590 optionalDependencies: 4591 - postcss: 8.5.3 4591 + postcss: 8.5.4 4592 4592 4593 - postcss-nested@6.2.0(postcss@8.5.3): 4593 + postcss-nested@6.2.0(postcss@8.5.4): 4594 4594 dependencies: 4595 - postcss: 8.5.3 4595 + postcss: 8.5.4 4596 4596 postcss-selector-parser: 6.1.2 4597 4597 4598 4598 postcss-selector-parser@6.1.2: ··· 4602 4602 4603 4603 postcss-value-parser@4.2.0: {} 4604 4604 4605 - postcss@8.5.3: 4605 + postcss@8.5.4: 4606 4606 dependencies: 4607 4607 nanoid: 3.3.11 4608 4608 picocolors: 1.1.1 ··· 4861 4861 normalize-path: 3.0.0 4862 4862 object-hash: 3.0.0 4863 4863 picocolors: 1.1.1 4864 - postcss: 8.5.3 4865 - postcss-import: 15.1.0(postcss@8.5.3) 4866 - postcss-js: 4.0.1(postcss@8.5.3) 4867 - postcss-load-config: 4.0.2(postcss@8.5.3) 4868 - postcss-nested: 6.2.0(postcss@8.5.3) 4864 + postcss: 8.5.4 4865 + postcss-import: 15.1.0(postcss@8.5.4) 4866 + postcss-js: 4.0.1(postcss@8.5.4) 4867 + postcss-load-config: 4.0.2(postcss@8.5.4) 4868 + postcss-nested: 6.2.0(postcss@8.5.4) 4869 4869 postcss-selector-parser: 6.1.2 4870 4870 resolve: 1.22.10 4871 4871 sucrase: 3.35.0 ··· 4951 4951 4952 4952 upath@1.2.0: {} 4953 4953 4954 - update-browserslist-db@1.1.3(browserslist@4.24.5): 4954 + update-browserslist-db@1.1.3(browserslist@4.25.0): 4955 4955 dependencies: 4956 - browserslist: 4.24.5 4956 + browserslist: 4.25.0 4957 4957 escalade: 3.2.0 4958 4958 picocolors: 1.1.1 4959 4959 ··· 4991 4991 esbuild: 0.25.5 4992 4992 fdir: 6.4.5(picomatch@4.0.2) 4993 4993 picomatch: 4.0.2 4994 - postcss: 8.5.3 4994 + postcss: 8.5.4 4995 4995 rollup: 4.41.1 4996 4996 tinyglobby: 0.2.14 4997 4997 optionalDependencies: ··· 5134 5134 '@types/trusted-types': 2.0.7 5135 5135 workbox-core: 7.3.0 5136 5136 5137 - workerd@1.20250523.0: 5137 + workerd@1.20250525.0: 5138 5138 optionalDependencies: 5139 - '@cloudflare/workerd-darwin-64': 1.20250523.0 5140 - '@cloudflare/workerd-darwin-arm64': 1.20250523.0 5141 - '@cloudflare/workerd-linux-64': 1.20250523.0 5142 - '@cloudflare/workerd-linux-arm64': 1.20250523.0 5143 - '@cloudflare/workerd-windows-64': 1.20250523.0 5139 + '@cloudflare/workerd-darwin-64': 1.20250525.0 5140 + '@cloudflare/workerd-darwin-arm64': 1.20250525.0 5141 + '@cloudflare/workerd-linux-64': 1.20250525.0 5142 + '@cloudflare/workerd-linux-arm64': 1.20250525.0 5143 + '@cloudflare/workerd-windows-64': 1.20250525.0 5144 5144 5145 - wrangler@4.17.0: 5145 + wrangler@4.18.0: 5146 5146 dependencies: 5147 5147 '@cloudflare/kv-asset-handler': 0.4.0 5148 - '@cloudflare/unenv-preset': 2.3.2(unenv@2.0.0-rc.17)(workerd@1.20250523.0) 5148 + '@cloudflare/unenv-preset': 2.3.2(unenv@2.0.0-rc.17)(workerd@1.20250525.0) 5149 5149 blake3-wasm: 2.1.5 5150 5150 esbuild: 0.25.4 5151 - miniflare: 4.20250523.0 5151 + miniflare: 4.20250525.0 5152 5152 path-to-regexp: 6.3.0 5153 5153 unenv: 2.0.0-rc.17 5154 - workerd: 1.20250523.0 5154 + workerd: 1.20250525.0 5155 5155 optionalDependencies: 5156 5156 fsevents: 2.3.3 5157 5157 transitivePeerDependencies:
+1 -1
src/api/cache/post-shadow.ts
··· 1 1 import { type Accessor, batch, createRenderEffect, createSignal, onCleanup } from 'solid-js'; 2 2 3 - import type { AppBskyFeedDefs } from '@atcute/client/lexicons'; 3 + import type { AppBskyFeedDefs } from '@atcute/bluesky'; 4 4 import { EventEmitter } from '@mary/events'; 5 5 import type { QueryClient } from '@mary/solid-query'; 6 6
+5 -4
src/api/cache/profile-shadow.ts
··· 1 1 import { type Accessor, batch, createRenderEffect, createSignal, onCleanup } from 'solid-js'; 2 2 3 - import type { AppBskyActorDefs, At } from '@atcute/client/lexicons'; 3 + import type { AppBskyActorDefs } from '@atcute/bluesky'; 4 + import type { Did } from '@atcute/lexicons'; 4 5 import { EventEmitter } from '@mary/events'; 5 6 import type { QueryClient } from '@mary/solid-query'; 6 7 ··· 33 34 | AppBskyActorDefs.ProfileViewBasic 34 35 | AppBskyActorDefs.ProfileViewDetailed; 35 36 36 - const emitter = new EventEmitter<{ [uri: At.Did]: [] }>(); 37 + const emitter = new EventEmitter<{ [uri: Did]: [] }>(); 37 38 const shadows = new WeakMap<AllProfileView, ProfileShadow>(); 38 39 39 40 export const useProfileShadow = (profile: AccessorMaybe<AllProfileView>): Accessor<ProfileShadowView> => { ··· 66 67 }; 67 68 }; 68 69 69 - export const updateProfileShadow = (queryClient: QueryClient, did: At.Did, value: Partial<ProfileShadow>) => { 70 + export const updateProfileShadow = (queryClient: QueryClient, did: Did, value: Partial<ProfileShadow>) => { 70 71 for (const profile of findProfilesInCache(queryClient, did)) { 71 72 shadows.set(profile, { ...shadows.get(profile), ...value }); 72 73 } ··· 74 75 batch(() => emitter.emit(did)); 75 76 }; 76 77 77 - export function findProfilesInCache(queryClient: QueryClient, did: At.Did): Generator<AllProfileView> { 78 + export function findProfilesInCache(queryClient: QueryClient, did: Did): Generator<AllProfileView> { 78 79 return iterateQueryCache<AllProfileView>(queryClient, [ 79 80 findAllProfilesInBookmarkFeed(did), 80 81 findAllProfilesInNotificationFeed(did),
+7 -12
src/api/models/post-thread.tsx
··· 1 - import type { 2 - AppBskyFeedDefs, 3 - AppBskyFeedGetPostThread, 4 - AppBskyFeedPost, 5 - At, 6 - Brand, 7 - } from '@atcute/client/lexicons'; 1 + import type { AppBskyFeedDefs, AppBskyFeedGetPostThread, AppBskyFeedPost } from '@atcute/bluesky'; 2 + import type { $type, Did } from '@atcute/lexicons'; 8 3 9 4 import type { ThreadViewPreferences } from '~/lib/preferences/account'; 10 5 ··· 87 82 88 83 export const fillModerationCache = ( 89 84 cache: ThreadModerationCache, 90 - thread: AppBskyFeedGetPostThread.Output['thread'], 85 + thread: AppBskyFeedGetPostThread.$output['thread'], 91 86 options: ModerationOptions, 92 87 ) => { 93 88 if (thread.$type === 'app.bsky.feed.defs#threadViewPost') { ··· 116 111 moderationOptions, 117 112 selfDid, 118 113 }: { 119 - thread: Brand.Union<AppBskyFeedDefs.ThreadViewPost>; 114 + thread: $type.enforce<AppBskyFeedDefs.ThreadViewPost>; 120 115 preferences: ThreadViewPreferences; 121 116 moderationOptions: ModerationOptions; 122 - selfDid?: At.Did; 117 + selfDid?: Did; 123 118 }): ThreadData => { 124 119 const { followsFirst, sort, treeView } = preferences; 125 120 ··· 166 161 167 162 if (last && last.type === 'post') { 168 163 const post = last.post; 169 - const reply = (post.record as AppBskyFeedPost.Record).reply; 164 + const reply = (post.record as AppBskyFeedPost.Main).reply; 170 165 171 166 if (reply) { 172 167 const uri = reply.parent.uri; ··· 205 200 206 201 // Filter the replies to only what we want 207 202 const items = replies.filter( 208 - (x): x is Brand.Union<AppBskyFeedDefs.ThreadViewPost | AppBskyFeedDefs.BlockedPost> => { 203 + (x): x is $type.enforce<AppBskyFeedDefs.ThreadViewPost | AppBskyFeedDefs.BlockedPost> => { 209 204 return ( 210 205 x.$type === 'app.bsky.feed.defs#threadViewPost' || 211 206 (x.$type === 'app.bsky.feed.defs#blockedPost' && !x.author.viewer?.blockedBy)
+1 -1
src/api/models/timeline.ts
··· 1 - import type { AppBskyActorDefs, AppBskyFeedDefs } from '@atcute/client/lexicons'; 1 + import type { AppBskyActorDefs, AppBskyFeedDefs } from '@atcute/bluesky'; 2 2 3 3 type Post = AppBskyFeedDefs.PostView; 4 4 type TimelineItem = AppBskyFeedDefs.FeedViewPost;
+3 -2
src/api/moderation/entities/generic.ts
··· 1 - import type { At, ComAtprotoLabelDefs } from '@atcute/client/lexicons'; 1 + import type { ComAtprotoLabelDefs } from '@atcute/atproto'; 2 + import type { Did } from '@atcute/lexicons'; 2 3 3 4 import { type ModerationCause, type ModerationOptions, decideLabelModeration } from '..'; 4 5 import { TargetContent } from '../constants'; 5 6 6 7 export const moderateGeneric = ( 7 8 item: { labels?: ComAtprotoLabelDefs.Label[] }, 8 - userDid: At.Did, 9 + userDid: Did, 9 10 opts: ModerationOptions, 10 11 ) => { 11 12 const accu: ModerationCause[] = [];
+2 -2
src/api/moderation/entities/post.ts
··· 1 - import type { AppBskyFeedDefs, AppBskyFeedPost } from '@atcute/client/lexicons'; 1 + import type { AppBskyFeedDefs, AppBskyFeedPost } from '@atcute/bluesky'; 2 2 3 3 import { unwrapPostEmbedText } from '~/api/utils/post'; 4 4 ··· 14 14 15 15 export const moderatePost = (post: AppBskyFeedDefs.PostView, opts: ModerationOptions) => { 16 16 const author = post.author; 17 - const record = post.record as AppBskyFeedPost.Record; 17 + const record = post.record as AppBskyFeedPost.Main; 18 18 const text = record.text + unwrapPostEmbedText(record.embed); 19 19 20 20 const accu: ModerationCause[] = moderateProfile(author, opts);
+1 -1
src/api/moderation/entities/profile.ts
··· 1 - import type { AppBskyActorDefs } from '@atcute/client/lexicons'; 1 + import type { AppBskyActorDefs } from '@atcute/bluesky'; 2 2 3 3 import { 4 4 type ModerationCause,
+2 -2
src/api/moderation/entities/quote.ts
··· 1 - import type { AppBskyEmbedRecord, AppBskyFeedPost } from '@atcute/client/lexicons'; 1 + import type { AppBskyEmbedRecord, AppBskyFeedPost } from '@atcute/bluesky'; 2 2 3 3 import { unwrapPostEmbedText } from '~/api/utils/post'; 4 4 ··· 14 14 15 15 export const moderateQuote = (quote: AppBskyEmbedRecord.ViewRecord, opts: ModerationOptions) => { 16 16 const author = quote.author; 17 - const record = quote.value as AppBskyFeedPost.Record; 17 + const record = quote.value as AppBskyFeedPost.Main; 18 18 const text = record.text + unwrapPostEmbedText(record.embed); 19 19 20 20 const accu: ModerationCause[] = moderateProfile(author, opts);
+7 -6
src/api/moderation/index.ts
··· 1 - import type { At, ComAtprotoLabelDefs } from '@atcute/client/lexicons'; 1 + import type { ComAtprotoLabelDefs } from '@atcute/atproto'; 2 + import type { Did } from '@atcute/lexicons'; 2 3 3 4 import { 4 5 BlurContent, ··· 280 281 281 282 export interface ModerationLabeler { 282 283 /** DID of the labeler */ 283 - did: At.Did; 284 + did: Did; 284 285 /** Profile details of the labeler */ 285 286 profile: { 286 287 avatar?: string; ··· 309 310 /** Preferences for global-defined labels */ 310 311 labels: LabelPreferenceMapping; 311 312 /** Preferences for labels from subscribed labelers */ 312 - labelers: Record<At.Did, ModerationLabelerPreferences>; 313 + labelers: Record<Did, ModerationLabelerPreferences>; 313 314 /** Keyword filters */ 314 315 keywords: KeywordFilter[]; 315 316 316 317 /** List of users to hide reposts from */ 317 - hideReposts: At.Did[]; 318 + hideReposts: Did[]; 318 319 } 319 320 320 321 export interface ModerationOptions { 321 322 _filtersCache?: [raw: string, match: RegExp][]; 322 323 323 324 preferences: ModerationPreferences; 324 - labelerDefinitions: Record<At.Did, ModerationLabeler>; 325 + labelerDefinitions: Record<Did, ModerationLabeler>; 325 326 } 326 327 327 328 export const decideLabelModeration = ( 328 329 accu: ModerationCause[], 329 330 target: LabelTarget, 330 331 labels: Label[] | undefined, 331 - userDid: At.Did, 332 + userDid: Did, 332 333 opts: ModerationOptions, 333 334 ) => { 334 335 if (labels /* && labels.length > 0 */) {
+1 -1
src/api/moderation/labeler.ts
··· 1 - import type { AppBskyLabelerDefs } from '@atcute/client/lexicons'; 1 + import type { AppBskyLabelerDefs } from '@atcute/bluesky'; 2 2 import { mapDefined } from '@mary/array-fns'; 3 3 4 4 import type { LabelDefinitionMapping, ModerationLabeler } from '.';
+4 -4
src/api/mutations/post.ts
··· 1 - import type { AppBskyFeedDefs } from '@atcute/client/lexicons'; 1 + import type { AppBskyFeedDefs } from '@atcute/bluesky'; 2 2 import { useQueryClient } from '@mary/solid-query'; 3 3 4 4 import { useAgent } from '~/lib/states/agent'; 5 5 import { useSession } from '~/lib/states/session'; 6 6 7 7 import { type PostShadowView, updatePostShadow } from '../cache/post-shadow'; 8 - import { parseCanonicalResourceUri } from '../types/at-uri'; 8 + import { assertCanonicalResourceUri } from '../types/at-uri'; 9 9 import { getCurrentDate } from '../utils/misc'; 10 10 import { createRecord, deleteRecord } from '../utils/records'; 11 11 import { createToggleMutationQueue } from '../utils/toggle-mutation'; ··· 45 45 46 46 return result.uri; 47 47 } else if (prevLikeUri) { 48 - const uri = parseCanonicalResourceUri(prevLikeUri); 48 + const uri = assertCanonicalResourceUri(prevLikeUri); 49 49 50 50 await deleteRecord(client, { 51 51 repo: currentAccount!.did, ··· 104 104 105 105 return result.uri; 106 106 } else if (prevRepostUri) { 107 - const uri = parseCanonicalResourceUri(prevRepostUri); 107 + const uri = assertCanonicalResourceUri(prevRepostUri); 108 108 109 109 await deleteRecord(client, { 110 110 repo: currentAccount!.did,
+3 -3
src/api/mutations/profile.ts
··· 1 - import type { AppBskyActorDefs } from '@atcute/client/lexicons'; 1 + import type { AppBskyActorDefs } from '@atcute/bluesky'; 2 2 import { useQueryClient } from '@mary/solid-query'; 3 3 4 4 import { useAgent } from '~/lib/states/agent'; 5 5 import { useSession } from '~/lib/states/session'; 6 6 7 7 import { type ProfileShadowView, updateProfileShadow } from '../cache/profile-shadow'; 8 - import { parseCanonicalResourceUri } from '../types/at-uri'; 8 + import { assertCanonicalResourceUri } from '../types/at-uri'; 9 9 import { getCurrentDate } from '../utils/misc'; 10 10 import { createRecord, deleteRecord } from '../utils/records'; 11 11 import { createToggleMutationQueue } from '../utils/toggle-mutation'; ··· 42 42 43 43 return result.uri; 44 44 } else if (prevFollowUri) { 45 - const uri = parseCanonicalResourceUri(prevFollowUri); 45 + const uri = assertCanonicalResourceUri(prevFollowUri); 46 46 47 47 await deleteRecord(client, { 48 48 repo: currentAccount!.did,
+3 -2
src/api/queries-cache/bookmark-feed.ts
··· 1 - import type { AppBskyActorDefs, AppBskyFeedDefs, At } from '@atcute/client/lexicons'; 1 + import type { AppBskyActorDefs, AppBskyFeedDefs } from '@atcute/bluesky'; 2 + import type { Did } from '@atcute/lexicons'; 2 3 import type { InfiniteData } from '@mary/solid-query'; 3 4 4 5 import type { CacheMatcher } from '../cache/utils'; ··· 35 36 }; 36 37 }; 37 38 38 - export const findAllProfiles = (did: At.Did): CacheMatcher<AppBskyActorDefs.ProfileViewBasic> => { 39 + export const findAllProfiles = (did: Did): CacheMatcher<AppBskyActorDefs.ProfileViewBasic> => { 39 40 return { 40 41 filter: { 41 42 queryKey: ['bookmarks-feed'],
+1 -1
src/api/queries-cache/feed-precache.ts
··· 1 - import type { AppBskyFeedDefs } from '@atcute/client/lexicons'; 1 + import type { AppBskyFeedDefs } from '@atcute/bluesky'; 2 2 import type { QueryClient } from '@mary/solid-query'; 3 3 4 4 export const precacheFeed = (queryClient: QueryClient, feed: AppBskyFeedDefs.GeneratorView) => {
+1 -1
src/api/queries-cache/list-precache.ts
··· 1 - import type { AppBskyGraphDefs } from '@atcute/client/lexicons'; 1 + import type { AppBskyGraphDefs } from '@atcute/bluesky'; 2 2 import type { QueryClient } from '@mary/solid-query'; 3 3 4 4 export const precacheList = (
+3 -2
src/api/queries-cache/notification-feed.ts
··· 1 - import type { AppBskyActorDefs, AppBskyFeedDefs, At } from '@atcute/client/lexicons'; 1 + import type { AppBskyActorDefs, AppBskyFeedDefs } from '@atcute/bluesky'; 2 + import type { Did } from '@atcute/lexicons'; 2 3 import type { InfiniteData } from '@mary/solid-query'; 3 4 4 5 import type { CacheMatcher } from '../cache/utils'; ··· 38 39 }; 39 40 40 41 export const findAllProfiles = ( 41 - did: At.Did, 42 + did: Did, 42 43 ): CacheMatcher<AppBskyActorDefs.ProfileViewBasic | AppBskyActorDefs.ProfileView> => { 43 44 return { 44 45 filter: {
+2 -2
src/api/queries-cache/post-quotes.ts
··· 1 - import type { AppBskyFeedDefs, AppBskyFeedGetQuotes } from '@atcute/client/lexicons'; 1 + import type { AppBskyFeedDefs, AppBskyFeedGetQuotes } from '@atcute/bluesky'; 2 2 import type { InfiniteData } from '@mary/solid-query'; 3 3 4 4 import type { CacheMatcher } from '../cache/utils'; ··· 9 9 filter: { 10 10 queryKey: ['post-quotes'], 11 11 }, 12 - *iterate(data: InfiniteData<AppBskyFeedGetQuotes.Output>) { 12 + *iterate(data: InfiniteData<AppBskyFeedGetQuotes.$output>) { 13 13 for (const page of data.pages) { 14 14 for (const post of page.posts) { 15 15 if (post.uri === uri) {
+8 -12
src/api/queries-cache/post-thread.ts
··· 1 - import type { 2 - AppBskyActorDefs, 3 - AppBskyFeedDefs, 4 - AppBskyFeedGetPostThread, 5 - At, 6 - } from '@atcute/client/lexicons'; 1 + import type { AppBskyActorDefs, AppBskyFeedDefs, AppBskyFeedGetPostThread } from '@atcute/bluesky'; 2 + import type { Did } from '@atcute/lexicons'; 7 3 8 4 import type { CacheMatcher } from '../cache/utils'; 9 5 import { embedViewRecordToPostView, getEmbeddedPost } from '../utils/post'; 10 6 11 - function* traverseThread( 12 - node: AppBskyFeedGetPostThread.Output['thread'], 13 - ): Generator<AppBskyFeedDefs.ThreadViewPost> { 7 + type Thread = AppBskyFeedGetPostThread.$output['thread']; 8 + 9 + function* traverseThread(node: Thread): Generator<AppBskyFeedDefs.ThreadViewPost> { 14 10 if (node.$type === 'app.bsky.feed.defs#threadViewPost') { 15 11 const parent = node.parent; 16 12 const replies = node.replies; ··· 35 31 filter: { 36 32 queryKey: ['post-thread'], 37 33 }, 38 - *iterate(data: AppBskyFeedGetPostThread.Output['thread']) { 34 + *iterate(data: Thread) { 39 35 for (const thread of traverseThread(data)) { 40 36 const post = thread.post; 41 37 ··· 54 50 }; 55 51 }; 56 52 57 - export const findAllProfiles = (did: At.Did): CacheMatcher<AppBskyActorDefs.ProfileViewBasic> => { 53 + export const findAllProfiles = (did: Did): CacheMatcher<AppBskyActorDefs.ProfileViewBasic> => { 58 54 return { 59 55 filter: { 60 56 queryKey: ['post-thread'], 61 57 }, 62 - *iterate(data: AppBskyFeedGetPostThread.Output['thread']) { 58 + *iterate(data: Thread) { 63 59 for (const thread of traverseThread(data)) { 64 60 const post = thread.post; 65 61
+4 -3
src/api/queries-cache/profile-autocomplete.ts
··· 1 - import type { AppBskyActorDefs, AppBskyActorSearchActorsTypeahead, At } from '@atcute/client/lexicons'; 1 + import type { AppBskyActorDefs, AppBskyActorSearchActorsTypeahead } from '@atcute/bluesky'; 2 + import type { Did } from '@atcute/lexicons'; 2 3 3 4 import type { CacheMatcher } from '../cache/utils'; 4 5 5 - export const findAllProfiles = (did: At.Did): CacheMatcher<AppBskyActorDefs.ProfileViewBasic> => { 6 + export const findAllProfiles = (did: Did): CacheMatcher<AppBskyActorDefs.ProfileViewBasic> => { 6 7 return { 7 8 filter: { 8 9 queryKey: ['profile-autocomplete'], 9 10 }, 10 - *iterate(data: AppBskyActorSearchActorsTypeahead.Output) { 11 + *iterate(data: AppBskyActorSearchActorsTypeahead.$output) { 11 12 for (const profile of data.actors) { 12 13 if (profile.did === did) { 13 14 yield profile;
+3 -2
src/api/queries-cache/profile-list.ts
··· 1 - import type { AppBskyActorDefs, At } from '@atcute/client/lexicons'; 1 + import type { AppBskyActorDefs } from '@atcute/bluesky'; 2 + import type { Did } from '@atcute/lexicons'; 2 3 import type { InfiniteData } from '@mary/solid-query'; 3 4 4 5 import type { CacheMatcher } from '../cache/utils'; 5 6 import type { ProfilesListPage, ProfilesListWithSubjectPage } from '../types/profile-response'; 6 7 7 - export const findAllProfiles = (did: At.Did): CacheMatcher<AppBskyActorDefs.ProfileView> => { 8 + export const findAllProfiles = (did: Did): CacheMatcher<AppBskyActorDefs.ProfileView> => { 8 9 return { 9 10 filter: [ 10 11 { queryKey: ['profile-followers'] },
+1 -1
src/api/queries-cache/profile-precache.ts
··· 1 - import type { AppBskyActorDefs } from '@atcute/client/lexicons'; 1 + import type { AppBskyActorDefs } from '@atcute/bluesky'; 2 2 import type { QueryClient } from '@mary/solid-query'; 3 3 4 4 export const precacheProfile = (
+3 -2
src/api/queries-cache/profile.ts
··· 1 - import type { AppBskyActorDefs, At } from '@atcute/client/lexicons'; 1 + import { AppBskyActorDefs } from '@atcute/bluesky'; 2 + import type { Did } from '@atcute/lexicons'; 2 3 3 4 import type { CacheMatcher } from '../cache/utils'; 4 5 5 - export const findAllProfiles = (did: At.Did): CacheMatcher<AppBskyActorDefs.ProfileViewDetailed> => { 6 + export const findAllProfiles = (did: Did): CacheMatcher<AppBskyActorDefs.ProfileViewDetailed> => { 6 7 return { 7 8 filter: { 8 9 queryKey: ['profile', did],
+3 -2
src/api/queries-cache/timeline.ts
··· 1 - import type { AppBskyActorDefs, AppBskyFeedDefs, At } from '@atcute/client/lexicons'; 1 + import type { AppBskyActorDefs, AppBskyFeedDefs } from '@atcute/bluesky'; 2 + import type { Did } from '@atcute/lexicons'; 2 3 import type { InfiniteData } from '@mary/solid-query'; 3 4 4 5 import type { CacheMatcher } from '../cache/utils'; ··· 63 64 }; 64 65 }; 65 66 66 - export const findAllProfiles = (did: At.Did): CacheMatcher<AppBskyActorDefs.ProfileViewBasic> => { 67 + export const findAllProfiles = (did: Did): CacheMatcher<AppBskyActorDefs.ProfileViewBasic> => { 67 68 return { 68 69 filter: { 69 70 queryKey: ['timeline'],
+2 -2
src/api/queries/blob.ts
··· 1 1 import { type Client, ok } from '@atcute/client'; 2 - import type { At } from '@atcute/client/lexicons'; 2 + import type { Blob as AtpBlob } from '@atcute/lexicons'; 3 3 4 - export const uploadBlob = async (client: Client, blob: Blob): Promise<At.Blob<any>> => { 4 + export const uploadBlob = async (client: Client, blob: Blob): Promise<AtpBlob<any>> => { 5 5 const data = await ok( 6 6 client.post('com.atproto.repo.uploadBlob', { 7 7 input: blob,
+1 -1
src/api/queries/bookmark-feed.ts
··· 1 + import type { AppBskyFeedDefs } from '@atcute/bluesky'; 1 2 import { tokenize } from '@atcute/bluesky-search-parser'; 2 3 import { ok } from '@atcute/client'; 3 - import type { AppBskyFeedDefs } from '@atcute/client/lexicons'; 4 4 import { mapDefined } from '@mary/array-fns'; 5 5 import { filter, map, take, toArray } from '@mary/async-iterator-fns'; 6 6 import { createInfiniteQuery, createQuery } from '@mary/solid-query';
+3 -3
src/api/queries/composer.ts
··· 1 - import type { At } from '@atcute/client/lexicons'; 1 + import type { GenericUri } from '@atcute/lexicons'; 2 2 import { createQuery } from '@mary/solid-query'; 3 3 4 4 const LINK_PROXY_ENDPOINT = 'https://cardyb.bsky.app/v1/extract'; ··· 13 13 } 14 14 15 15 export interface LinkMeta { 16 - uri: At.GenericUri; 16 + uri: GenericUri; 17 17 title: string; 18 18 description: string; 19 19 thumb: Blob | undefined; ··· 57 57 } 58 58 59 59 const meta: LinkMeta = { 60 - uri: $uri as At.GenericUri, 60 + uri: $uri as GenericUri, 61 61 title: data.title, 62 62 description: data.description, 63 63 thumb: thumb,
+5 -4
src/api/queries/feed.ts
··· 1 1 import { modifyMutable, reconcile } from 'solid-js/store'; 2 2 3 + import type { AppBskyFeedDefs } from '@atcute/bluesky'; 3 4 import { ok } from '@atcute/client'; 4 - import type { AppBskyFeedDefs, At } from '@atcute/client/lexicons'; 5 + import { type Did } from '@atcute/lexicons'; 5 6 import { createQuery } from '@mary/solid-query'; 6 7 7 8 import type { SavedGeneratorFeed } from '~/lib/preferences/account'; ··· 9 10 import { useSession } from '~/lib/states/session'; 10 11 import { omit } from '~/lib/utils/misc'; 11 12 12 - import { makeAtUri, parseCanonicalResourceUri } from '../types/at-uri'; 13 + import { assertCanonicalResourceUri, makeAtUri } from '../types/at-uri'; 13 14 import { isDid } from '../types/identity'; 14 15 15 16 import { resolveHandle } from './handle'; ··· 24 25 return { 25 26 queryKey: ['feed-meta', $feedUri], 26 27 async queryFn(ctx): Promise<AppBskyFeedDefs.GeneratorView> { 27 - const uri = parseCanonicalResourceUri($feedUri); 28 + const uri = assertCanonicalResourceUri($feedUri); 28 29 29 - let did: At.Did; 30 + let did: Did; 30 31 if (isDid(uri.repo)) { 31 32 did = uri.repo; 32 33 } else {
+3 -3
src/api/queries/handle.ts
··· 1 1 import { type Client, ok } from '@atcute/client'; 2 - import type { At } from '@atcute/client/lexicons'; 2 + import type { Handle } from '@atcute/lexicons'; 3 3 import { createQuery } from '@mary/solid-query'; 4 4 5 5 import { useAgent } from '~/lib/states/agent'; 6 6 7 - export const useResolveHandleQuery = (handle: () => At.Handle) => { 7 + export const useResolveHandleQuery = (handle: () => Handle) => { 8 8 const { client } = useAgent(); 9 9 10 10 return createQuery(() => { ··· 19 19 }); 20 20 }; 21 21 22 - export const resolveHandle = async (client: Client, handle: At.Handle, signal?: AbortSignal) => { 22 + export const resolveHandle = async (client: Client, handle: Handle, signal?: AbortSignal) => { 23 23 const data = await ok( 24 24 client.get('com.atproto.identity.resolveHandle', { 25 25 signal: signal,
+3 -2
src/api/queries/labeler.ts
··· 1 + import type { AppBskyLabelerDefs } from '@atcute/bluesky'; 1 2 import { ClientResponseError, ok } from '@atcute/client'; 2 - import type { AppBskyLabelerDefs, At } from '@atcute/client/lexicons'; 3 + import type { Did } from '@atcute/lexicons'; 3 4 import { createQuery } from '@mary/solid-query'; 4 5 5 6 import { useAgent } from '~/lib/states/agent'; 6 7 7 8 import { interpretLabelerDefinition } from '../moderation/labeler'; 8 9 9 - export const createLabelerMetaQuery = (did: () => At.Did) => { 10 + export const createLabelerMetaQuery = (did: () => Did) => { 10 11 const { client } = useAgent(); 11 12 12 13 const query = createQuery(() => {
+2 -2
src/api/queries/list-members.ts
··· 1 1 import { ok } from '@atcute/client'; 2 - import type { At } from '@atcute/client/lexicons'; 2 + import type { ResourceUri } from '@atcute/lexicons'; 3 3 import { type QueryFunctionContext as QC, createInfiniteQuery } from '@mary/solid-query'; 4 4 5 5 import { useAgent } from '~/lib/states/agent'; 6 6 7 - export const createListMembersQuery = (listUri: () => At.ResourceUri) => { 7 + export const createListMembersQuery = (listUri: () => ResourceUri) => { 8 8 const { client } = useAgent(); 9 9 10 10 return createInfiniteQuery(() => {
+5 -4
src/api/queries/list.ts
··· 1 1 import { modifyMutable, reconcile } from 'solid-js/store'; 2 2 3 + import type { AppBskyGraphDefs } from '@atcute/bluesky'; 3 4 import { ok } from '@atcute/client'; 4 - import type { AppBskyGraphDefs, At } from '@atcute/client/lexicons'; 5 + import { type Did } from '@atcute/lexicons'; 5 6 import { createQuery } from '@mary/solid-query'; 6 7 7 8 import type { SavedListFeed } from '~/lib/preferences/account'; ··· 9 10 import { useSession } from '~/lib/states/session'; 10 11 import { omit } from '~/lib/utils/misc'; 11 12 12 - import { makeAtUri, parseCanonicalResourceUri } from '../types/at-uri'; 13 + import { assertCanonicalResourceUri, makeAtUri } from '../types/at-uri'; 13 14 import { isDid } from '../types/identity'; 14 15 15 16 import { resolveHandle } from './handle'; ··· 24 25 return { 25 26 queryKey: ['list-meta', $listUri], 26 27 async queryFn(ctx) { 27 - const uri = parseCanonicalResourceUri($listUri); 28 + const uri = assertCanonicalResourceUri($listUri); 28 29 29 - let did: At.Did; 30 + let did: Did; 30 31 if (isDid(uri.repo)) { 31 32 did = uri.repo; 32 33 } else {
+1 -1
src/api/queries/my-lists.ts
··· 1 + import type { AppBskyGraphDefs } from '@atcute/bluesky'; 1 2 import { ok } from '@atcute/client'; 2 - import type { AppBskyGraphDefs } from '@atcute/client/lexicons'; 3 3 import { createQuery } from '@mary/solid-query'; 4 4 5 5 import { useAgent } from '~/lib/states/agent';
+3 -3
src/api/queries/notification-feed.tsx
··· 1 1 import { createSignal } from 'solid-js'; 2 2 3 + import type { AppBskyFeedDefs, AppBskyNotificationListNotifications } from '@atcute/bluesky'; 3 4 import { ok } from '@atcute/client'; 4 - import type { AppBskyFeedDefs, AppBskyNotificationListNotifications } from '@atcute/client/lexicons'; 5 5 import { chunked, mapDefined } from '@mary/array-fns'; 6 6 import { type QueryFunctionContext as QC, createInfiniteQuery, useQueryClient } from '@mary/solid-query'; 7 7 8 8 import { useAgent } from '~/lib/states/agent'; 9 9 10 - import { parseCanonicalResourceUri } from '../types/at-uri'; 10 + import { assertCanonicalResourceUri } from '../types/at-uri'; 11 11 import { dequal } from '../utils/dequal'; 12 12 import { resetInfiniteData } from '../utils/query'; 13 13 ··· 134 134 // skip if they're not related to posts. 135 135 if ( 136 136 !subjectUri || 137 - parseCanonicalResourceUri(subjectUri).collection !== 'app.bsky.feed.post' 137 + assertCanonicalResourceUri(subjectUri).collection !== 'app.bsky.feed.post' 138 138 ) { 139 139 return; 140 140 }
+4 -3
src/api/queries/post-quotes.ts
··· 1 + import type { AppBskyFeedGetQuotes } from '@atcute/bluesky'; 1 2 import { ok } from '@atcute/client'; 2 - import type { AppBskyFeedGetQuotes, At } from '@atcute/client/lexicons'; 3 + import type { ResourceUri } from '@atcute/lexicons'; 3 4 import { type QueryFunctionContext as QC, createInfiniteQuery } from '@mary/solid-query'; 4 5 5 6 import { useAgent } from '~/lib/states/agent'; 6 7 7 - export const createPostQuotesQuery = (uri: () => At.ResourceUri) => { 8 + export const createPostQuotesQuery = (uri: () => ResourceUri) => { 8 9 const { client } = useAgent(); 9 10 10 11 return createInfiniteQuery(() => { ··· 13 14 return { 14 15 queryKey: ['post-quotes', $uri], 15 16 structuralSharing: false, 16 - async queryFn(ctx: QC<never, string | undefined>): Promise<AppBskyFeedGetQuotes.Output> { 17 + async queryFn(ctx: QC<never, string | undefined>): Promise<AppBskyFeedGetQuotes.$output> { 17 18 const data = await ok( 18 19 client.get('app.bsky.feed.getQuotes', { 19 20 signal: ctx.signal,
+5 -4
src/api/queries/post-thread.ts
··· 1 + import type { AppBskyFeedDefs } from '@atcute/bluesky'; 1 2 import { ClientResponseError, ok } from '@atcute/client'; 2 - import type { AppBskyFeedDefs, At, Brand } from '@atcute/client/lexicons'; 3 + import type { $type, ResourceUri } from '@atcute/lexicons'; 3 4 import { createQuery } from '@mary/solid-query'; 4 5 5 6 import { useAgent } from '~/lib/states/agent'; ··· 9 10 const MAX_HEIGHT = 10; 10 11 const MAX_DEPTH = 4; 11 12 12 - type ThreadReturn = Brand.Union<AppBskyFeedDefs.ThreadViewPost | AppBskyFeedDefs.BlockedPost>; 13 + type ThreadReturn = $type.enforce<AppBskyFeedDefs.ThreadViewPost | AppBskyFeedDefs.BlockedPost>; 13 14 14 - export const usePostThreadQuery = (uri: () => At.ResourceUri) => { 15 + export const usePostThreadQuery = (uri: () => ResourceUri) => { 15 16 const { client } = useAgent(); 16 17 17 18 return createQuery((queryClient) => { ··· 56 57 // Break if either: 57 58 // - This isn't a quote embed transformed into a post view 58 59 // - We've went through 10 post views 59 - if (!('$transform' in found) || ++step >= 10) { 60 + if (!('$transform' in post) || ++step >= 10) { 60 61 break; 61 62 } 62 63 }
+4 -4
src/api/queries/post.ts
··· 1 1 import { ok } from '@atcute/client'; 2 - import type { At } from '@atcute/client/lexicons'; 2 + import { type Did } from '@atcute/lexicons'; 3 3 import { createQuery } from '@mary/solid-query'; 4 4 5 5 import { useAgent } from '~/lib/states/agent'; 6 6 7 7 import { findPostsInCache } from '../cache/post-shadow'; 8 - import { makeAtUri, parseCanonicalResourceUri } from '../types/at-uri'; 8 + import { assertCanonicalResourceUri, makeAtUri } from '../types/at-uri'; 9 9 import { isDid } from '../types/identity'; 10 10 11 11 import { resolveHandle } from './handle'; ··· 19 19 return { 20 20 queryKey: ['post', $postUri], 21 21 async queryFn(ctx) { 22 - const uri = parseCanonicalResourceUri($postUri); 22 + const uri = assertCanonicalResourceUri($postUri); 23 23 24 - let did: At.Did; 24 + let did: Did; 25 25 if (isDid(uri.repo)) { 26 26 did = uri.repo; 27 27 } else {
+2 -2
src/api/queries/profile-feeds.ts
··· 1 1 import { ok } from '@atcute/client'; 2 - import type { At } from '@atcute/client/lexicons'; 2 + import type { ActorIdentifier } from '@atcute/lexicons'; 3 3 import { type QueryFunctionContext as QC, createInfiniteQuery } from '@mary/solid-query'; 4 4 5 5 import { useAgent } from '~/lib/states/agent'; 6 6 7 - export const createProfileFeedsQuery = (didOrHandle: () => At.Identifier) => { 7 + export const createProfileFeedsQuery = (didOrHandle: () => ActorIdentifier) => { 8 8 const { client } = useAgent(); 9 9 10 10 return createInfiniteQuery(() => {
+3 -2
src/api/queries/profile-followers.ts
··· 1 + import type { AppBskyActorDefs } from '@atcute/bluesky'; 1 2 import { ok } from '@atcute/client'; 2 - import type { AppBskyActorDefs, At } from '@atcute/client/lexicons'; 3 + import type { ActorIdentifier } from '@atcute/lexicons'; 3 4 import { type InfiniteData, type QueryFunctionContext as QC, createInfiniteQuery } from '@mary/solid-query'; 4 5 5 6 import { useAgent } from '~/lib/states/agent'; 6 7 7 8 import { type ProfilesListWithSubjectPage, toProfilesListWithSubjectPage } from '../types/profile-response'; 8 9 9 - export const createProfileFollowersQuery = (didOrHandle: () => At.Identifier) => { 10 + export const createProfileFollowersQuery = (didOrHandle: () => ActorIdentifier) => { 10 11 const { client } = useAgent(); 11 12 12 13 return createInfiniteQuery((queryClient) => {
+3 -2
src/api/queries/profile-following.ts
··· 1 + import type { AppBskyActorDefs } from '@atcute/bluesky'; 1 2 import { ok } from '@atcute/client'; 2 - import type { AppBskyActorDefs, At } from '@atcute/client/lexicons'; 3 + import type { ActorIdentifier } from '@atcute/lexicons'; 3 4 import { type InfiniteData, type QueryFunctionContext as QC, createInfiniteQuery } from '@mary/solid-query'; 4 5 5 6 import { useAgent } from '~/lib/states/agent'; 6 7 7 8 import { type ProfilesListWithSubjectPage, toProfilesListWithSubjectPage } from '../types/profile-response'; 8 9 9 - export const createProfileFollowingQuery = (didOrHandle: () => At.Identifier) => { 10 + export const createProfileFollowingQuery = (didOrHandle: () => ActorIdentifier) => { 10 11 const { client } = useAgent(); 11 12 12 13 return createInfiniteQuery((queryClient) => {
+3 -2
src/api/queries/profile-known-followers.ts
··· 1 + import type { AppBskyActorDefs } from '@atcute/bluesky'; 1 2 import { ok } from '@atcute/client'; 2 - import type { AppBskyActorDefs, At } from '@atcute/client/lexicons'; 3 + import type { ActorIdentifier } from '@atcute/lexicons'; 3 4 import { type InfiniteData, type QueryFunctionContext as QC, createInfiniteQuery } from '@mary/solid-query'; 4 5 5 6 import { useAgent } from '~/lib/states/agent'; 6 7 7 8 import { type ProfilesListWithSubjectPage, toProfilesListWithSubjectPage } from '../types/profile-response'; 8 9 9 - export const createProfileKnownFollowersQuery = (didOrHandle: () => At.Identifier) => { 10 + export const createProfileKnownFollowersQuery = (didOrHandle: () => ActorIdentifier) => { 10 11 const { client } = useAgent(); 11 12 12 13 return createInfiniteQuery((queryClient) => {
+2 -2
src/api/queries/profile-lists.ts
··· 1 1 import { ok } from '@atcute/client'; 2 - import type { At } from '@atcute/client/lexicons'; 2 + import type { ActorIdentifier } from '@atcute/lexicons'; 3 3 import { type QueryFunctionContext as QC, createInfiniteQuery } from '@mary/solid-query'; 4 4 5 5 import { useAgent } from '~/lib/states/agent'; 6 6 7 - export const createProfileListsQuery = (didOrHandle: () => At.Identifier) => { 7 + export const createProfileListsQuery = (didOrHandle: () => ActorIdentifier) => { 8 8 const { client } = useAgent(); 9 9 10 10 const collator = new Intl.Collator('en-US');
+3 -2
src/api/queries/profile.ts
··· 1 1 import { modifyMutable, reconcile } from 'solid-js/store'; 2 2 3 + import type { AppBskyActorDefs } from '@atcute/bluesky'; 3 4 import { ok } from '@atcute/client'; 4 - import type { AppBskyActorDefs, At } from '@atcute/client/lexicons'; 5 + import type { ActorIdentifier } from '@atcute/lexicons'; 5 6 import { createQuery } from '@mary/solid-query'; 6 7 7 8 import { useAgent } from '~/lib/states/agent'; ··· 14 15 gcTime?: number; 15 16 } 16 17 17 - export const createProfileQuery = (didOrHandle: () => At.Identifier, opts: ProfileQueryOptions = {}) => { 18 + export const createProfileQuery = (didOrHandle: () => ActorIdentifier, opts: ProfileQueryOptions = {}) => { 18 19 const { client } = useAgent(); 19 20 const { currentAccount } = useSession(); 20 21
+2 -2
src/api/queries/search-feeds.ts
··· 1 + import type { AppBskyUnspeccedGetPopularFeedGenerators } from '@atcute/bluesky'; 1 2 import { ok } from '@atcute/client'; 2 - import type { AppBskyUnspeccedGetPopularFeedGenerators } from '@atcute/client/lexicons'; 3 3 import { type QueryFunctionContext as QC, createInfiniteQuery } from '@mary/solid-query'; 4 4 5 5 import { useAgent } from '~/lib/states/agent'; ··· 14 14 queryKey: ['search-feeds', q], 15 15 async queryFn( 16 16 ctx: QC<never, string | undefined>, 17 - ): Promise<AppBskyUnspeccedGetPopularFeedGenerators.Output> { 17 + ): Promise<AppBskyUnspeccedGetPopularFeedGenerators.$output> { 18 18 const data = await ok( 19 19 client.get('app.bsky.unspecced.getPopularFeedGenerators', { 20 20 signal: ctx.signal,
+2 -2
src/api/queries/subject-likers.ts
··· 1 1 import { ok } from '@atcute/client'; 2 - import type { At } from '@atcute/client/lexicons'; 2 + import type { ResourceUri } from '@atcute/lexicons'; 3 3 import type { QueryFunctionContext as QC } from '@mary/solid-query'; 4 4 import { createInfiniteQuery } from '@mary/solid-query'; 5 5 ··· 7 7 8 8 import type { ProfilesListPage } from '../types/profile-response'; 9 9 10 - export const createSubjectLikersQuery = (uri: () => At.ResourceUri) => { 10 + export const createSubjectLikersQuery = (uri: () => ResourceUri) => { 11 11 const { client } = useAgent(); 12 12 13 13 return createInfiniteQuery(() => {
+2 -2
src/api/queries/subject-reposters.ts
··· 1 1 import { ok } from '@atcute/client'; 2 - import type { At } from '@atcute/client/lexicons'; 2 + import type { ResourceUri } from '@atcute/lexicons'; 3 3 import type { QueryFunctionContext as QC } from '@mary/solid-query'; 4 4 import { createInfiniteQuery } from '@mary/solid-query'; 5 5 ··· 7 7 8 8 import { type ProfilesListPage, toProfilesListPage } from '../types/profile-response'; 9 9 10 - export const createSubjectRepostersQuery = (uri: () => At.ResourceUri) => { 10 + export const createSubjectRepostersQuery = (uri: () => ResourceUri) => { 11 11 const { client } = useAgent(); 12 12 13 13 return createInfiniteQuery(() => {
+20 -14
src/api/queries/timeline.ts
··· 1 1 import { createEffect, createMemo, createRenderEffect, onCleanup, untrack } from 'solid-js'; 2 2 3 + import { 4 + type AppBskyFeedDefs, 5 + type AppBskyFeedGetTimeline, 6 + type AppBskyFeedPost, 7 + unwrapRawRecordEmbed, 8 + unwrapRecordEmbed, 9 + } from '@atcute/bluesky'; 3 10 import { type Client, ok } from '@atcute/client'; 4 - import type { AppBskyFeedDefs, AppBskyFeedGetTimeline, AppBskyFeedPost, At } from '@atcute/client/lexicons'; 11 + import { type Did, type ResourceUri } from '@atcute/lexicons'; 5 12 import { type FalsyValue, definite } from '@mary/array-fns'; 6 13 import { type InfiniteData, createInfiniteQuery, createQuery, useQueryClient } from '@mary/solid-query'; 7 14 ··· 31 38 getModerationUI, 32 39 } from '../moderation'; 33 40 import { ContextContentList, PreferenceHide, TargetContent } from '../moderation/constants'; 34 - import { parseCanonicalResourceUri } from '../types/at-uri'; 35 - import { unwrapRecordEmbed } from '../utils/bluesky/embed'; 36 - import { unwrapRecordEmbedView } from '../utils/bluesky/embed-view'; 41 + import { assertCanonicalResourceUri } from '../types/at-uri'; 37 42 import { EQUALS_DEQUAL } from '../utils/dequal'; 38 43 import { unwrapPostEmbedText } from '../utils/post'; 39 44 import { resetInfiniteData, wrapQuery } from '../utils/query'; 40 45 41 - type PostRecord = AppBskyFeedPost.Record; 46 + type PostRecord = AppBskyFeedPost.Main; 42 47 43 48 export interface FollowingTimelineParams { 44 49 type: 'following'; ··· 49 54 50 55 export interface FeedTimelineParams { 51 56 type: 'feed'; 52 - uri: At.ResourceUri; 57 + uri: ResourceUri; 53 58 showReplies: boolean; 54 59 showReposts: boolean; 55 60 showQuotes: boolean; ··· 57 62 58 63 export interface ListTimelineParams { 59 64 type: 'list'; 60 - uri: At.ResourceUri; 65 + uri: ResourceUri; 61 66 showReplies: boolean; 62 67 showQuotes: boolean; 63 68 } 64 69 65 70 export interface ProfileTimelineParams { 66 71 type: 'profile'; 67 - actor: At.Did; 72 + actor: Did; 68 73 tab: 'posts' | 'replies' | 'likes' | 'media'; 69 74 } 70 75 ··· 313 318 limit: number, 314 319 cursor: string | undefined, 315 320 signal: AbortSignal, 316 - ): Promise<AppBskyFeedGetTimeline.Output> => { 321 + ): Promise<AppBskyFeedGetTimeline.$output> => { 317 322 const type = params.type; 318 323 319 324 if (type === 'following') { ··· 532 537 const createHideQuotesFilter = (): PostFilter => { 533 538 return (item) => { 534 539 const post = item.post.record as PostRecord; 535 - const record = unwrapRecordEmbed(post.embed); 540 + const record = unwrapRawRecordEmbed(post.embed); 536 541 537 542 return ( 538 - record === undefined || parseCanonicalResourceUri(record.record.uri).collection === 'app.bsky.feed.post' 543 + record === undefined || 544 + assertCanonicalResourceUri(record.record.uri).collection === 'app.bsky.feed.post' 539 545 ); 540 546 }; 541 547 }; ··· 543 549 const createHideQuotesFromMutedFilter = (): PostFilter => { 544 550 return (item) => { 545 551 const post = item.post; 546 - const record = unwrapRecordEmbedView(post.embed); 552 + const record = unwrapRecordEmbed(post.embed); 547 553 548 554 return ( 549 555 record === undefined || ··· 585 591 }; 586 592 }; 587 593 588 - const createHomeSliceFilter = (uid: At.Did, followsOnly: boolean): SliceFilter | undefined => { 594 + const createHomeSliceFilter = (uid: Did, followsOnly: boolean): SliceFilter | undefined => { 589 595 return (slice) => { 590 596 const items = slice.items; 591 597 const first = items[0]; ··· 617 623 }; 618 624 }; 619 625 620 - const createProfileSliceFilter = (did: At.Did): SliceFilter | undefined => { 626 + const createProfileSliceFilter = (did: Did): SliceFilter | undefined => { 621 627 return (slice) => { 622 628 const items = slice.items; 623 629 const first = items[0];
+20 -24
src/api/types/at-uri.ts
··· 1 - import type { At, Records } from '@atcute/client/lexicons'; 1 + import { 2 + type ActorIdentifier, 3 + type Nsid, 4 + type ParsedCanonicalResourceUri, 5 + type RecordKey, 6 + type ResourceUri, 7 + parseCanonicalResourceUri, 8 + } from '@atcute/lexicons'; 9 + import type { Records } from '@atcute/lexicons/ambient'; 2 10 3 11 import { assert } from '~/lib/utils/invariant'; 4 12 5 - export const ATURI_RE = 6 - /^at:\/\/(did:[a-z]+:[a-zA-Z0-9._:%\-]*[a-zA-Z0-9._\-]|(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z][a-zA-Z0-9-]{0,61}[a-zA-Z0-9])\/([a-zA-Z0-9-.]+)\/((?!\.{1,2}$)[a-zA-Z0-9_~.:-]{1,512})(?:#(\/[a-zA-Z0-9._~:@!$&%')(*+,;=\-[\]/\\]*))?$/; 7 - 8 - export interface ParsedCanonicalResourceUri { 9 - repo: At.Did; 10 - collection: At.Nsid; 11 - rkey: At.RecordKey; 12 - fragment: string | undefined; 13 - } 14 - 15 - export const parseCanonicalResourceUri = (str: string): ParsedCanonicalResourceUri => { 16 - const match = ATURI_RE.exec(str); 17 - assert(match !== null, `failed to parse canonical-at-uri for ${str}`); 13 + // #__NO_SIDE_EFFECTS__ 14 + export const assertCanonicalResourceUri = (input: string): ParsedCanonicalResourceUri => { 15 + const result = parseCanonicalResourceUri(input); 16 + if (!result.ok) { 17 + assert(false, result.error); 18 + } 18 19 19 - return { 20 - repo: match[1] as At.Did, 21 - collection: match[2] as At.Nsid, 22 - rkey: match[3] as At.RecordKey, 23 - fragment: match[4], 24 - }; 20 + return result.value; 25 21 }; 26 22 27 23 export const makeAtUri = ( 28 - repo: At.Identifier, 29 - collection: keyof Records | (string & {}), 30 - rkey: At.RecordKey, 31 - ): At.ResourceUri => { 24 + repo: ActorIdentifier, 25 + collection: keyof Records | (Nsid & {}), 26 + rkey: RecordKey, 27 + ): ResourceUri => { 32 28 return `at://${repo}/${collection}/${rkey}`; 33 29 };
+1 -1
src/api/types/profile-response.ts
··· 1 - import type { AppBskyActorDefs } from '@atcute/client/lexicons'; 1 + import type { AppBskyActorDefs } from '@atcute/bluesky'; 2 2 3 3 export interface ProfilesListPage { 4 4 cursor: string | undefined;
-56
src/api/utils/bluesky/embed-view.ts
··· 1 - import type { AppBskyEmbedRecordWithMedia, AppBskyFeedDefs } from '@atcute/client/lexicons'; 2 - 3 - import { parseCanonicalResourceUri } from '~/api/types/at-uri'; 4 - 5 - export interface EmbedsView { 6 - media?: AppBskyEmbedRecordWithMedia.View['media']; 7 - record?: AppBskyEmbedRecordWithMedia.View['record']['record']; 8 - } 9 - 10 - export type MediaEmbedView = NonNullable<EmbedsView['media']>; 11 - export type RecordEmbedView = NonNullable<EmbedsView['record']>; 12 - 13 - export const unwrapMediaEmbedView = (embed: AppBskyFeedDefs.PostView['embed']): EmbedsView['media'] => { 14 - switch (embed?.$type) { 15 - case 'app.bsky.embed.recordWithMedia#view': 16 - return embed.media; 17 - case 'app.bsky.embed.record#view': 18 - return; 19 - } 20 - 21 - return embed; 22 - }; 23 - 24 - export const unwrapRecordEmbedView = (embed: AppBskyFeedDefs.PostView['embed']): EmbedsView['record'] => { 25 - switch (embed?.$type) { 26 - case 'app.bsky.embed.recordWithMedia#view': 27 - return embed.record.record; 28 - 29 - case 'app.bsky.embed.record#view': 30 - return embed.record; 31 - } 32 - }; 33 - 34 - export const unwrapEmbedView = (embed: AppBskyFeedDefs.PostView['embed']): EmbedsView => { 35 - return { 36 - media: unwrapMediaEmbedView(embed), 37 - record: unwrapRecordEmbedView(embed), 38 - }; 39 - }; 40 - 41 - export const getQuoteEmbedView = (embed: RecordEmbedView | undefined) => { 42 - switch (embed?.$type) { 43 - case 'app.bsky.embed.record#viewRecord': { 44 - return embed; 45 - } 46 - 47 - case 'app.bsky.embed.record#viewNotFound': 48 - case 'app.bsky.embed.record#viewDetached': 49 - case 'app.bsky.embed.record#viewBlocked': { 50 - const uri = parseCanonicalResourceUri(embed.uri); 51 - if (uri.collection === 'app.bsky.feed.post') { 52 - return embed; 53 - } 54 - } 55 - } 56 - };
-37
src/api/utils/bluesky/embed.ts
··· 1 - import type { AppBskyEmbedRecordWithMedia, AppBskyFeedPost } from '@atcute/client/lexicons'; 2 - 3 - export interface Embeds { 4 - media?: AppBskyEmbedRecordWithMedia.Main['media']; 5 - record?: AppBskyEmbedRecordWithMedia.Main['record']; 6 - } 7 - 8 - export type MediaEmbed = NonNullable<Embeds['media']>; 9 - export type RecordEmbed = NonNullable<Embeds['record']>; 10 - 11 - export const unwrapMediaEmbed = (embed: AppBskyFeedPost.Record['embed']): Embeds['media'] => { 12 - switch (embed?.$type) { 13 - case 'app.bsky.embed.recordWithMedia': 14 - return embed.media; 15 - case 'app.bsky.embed.record': 16 - return; 17 - } 18 - 19 - return embed; 20 - }; 21 - 22 - export const unwrapRecordEmbed = (embed: AppBskyFeedPost.Record['embed']): Embeds['record'] => { 23 - switch (embed?.$type) { 24 - case 'app.bsky.embed.recordWithMedia': 25 - return embed.record; 26 - 27 - case 'app.bsky.embed.record': 28 - return embed; 29 - } 30 - }; 31 - 32 - export const unwrapEmbed = (embed: AppBskyFeedPost.Record['embed']): Embeds => { 33 - return { 34 - media: unwrapMediaEmbed(embed), 35 - record: unwrapRecordEmbed(embed), 36 - }; 37 - };
+3 -3
src/api/utils/did.ts
··· 1 1 import { type Client, ok } from '@atcute/client'; 2 - import type { At } from '@atcute/client/lexicons'; 2 + import type { Did, Handle } from '@atcute/lexicons'; 3 3 4 4 import { isDid } from '../types/identity'; 5 5 6 - const getDid = async (client: Client, actor: At.Handle, signal?: AbortSignal) => { 7 - let did: At.Did; 6 + const getDid = async (client: Client, actor: Handle, signal?: AbortSignal) => { 7 + let did: Did; 8 8 if (isDid(actor)) { 9 9 did = actor; 10 10 } else {
+6 -4
src/api/utils/post.ts
··· 4 4 AppBskyEmbedRecord, 5 5 AppBskyFeedDefs, 6 6 AppBskyFeedPost, 7 - Brand, 8 - } from '@atcute/client/lexicons'; 7 + } from '@atcute/bluesky'; 8 + import type { $type } from '@atcute/lexicons'; 9 9 10 - type RecordEmbed = AppBskyFeedPost.Record['embed']; 10 + type RecordEmbed = AppBskyFeedPost.Main['embed']; 11 11 type ViewEmbed = AppBskyFeedDefs.PostView['embed']; 12 12 13 13 export const unwrapPostEmbedText = (embed: RecordEmbed | ViewEmbed): string => { ··· 35 35 type RecordMedia = AppBskyEmbedExternal.Main | AppBskyEmbedImages.Main; 36 36 type ViewMedia = AppBskyEmbedExternal.View | AppBskyEmbedImages.View; 37 37 38 - const getMediaEmbed = (embed: RecordEmbed | ViewEmbed): Brand.Union<RecordMedia | ViewMedia> | undefined => { 38 + const getMediaEmbed = ( 39 + embed: RecordEmbed | ViewEmbed, 40 + ): $type.enforce<RecordMedia | ViewMedia> | undefined => { 39 41 if (embed) { 40 42 const type = embed.$type; 41 43
+20 -23
src/api/utils/records.ts
··· 1 + import type { ComAtprotoRepoGetRecord, ComAtprotoRepoListRecords } from '@atcute/atproto'; 1 2 import { type Client, ok } from '@atcute/client'; 2 - import type { 3 - At, 4 - ComAtprotoRepoGetRecord, 5 - ComAtprotoRepoListRecords, 6 - Records, 7 - } from '@atcute/client/lexicons'; 3 + import type { Cid, Did, InferInput, ResourceUri } from '@atcute/lexicons'; 4 + import type { Records } from '@atcute/lexicons/ambient'; 8 5 9 6 type RecordType = keyof Records; 10 7 11 8 export interface CreateRecordOptions<K extends RecordType> { 12 - repo: At.Did; 9 + repo: Did; 13 10 collection: K; 14 11 rkey?: string; 15 - record: Records[K]; 12 + record: InferInput<Records[K]>; 16 13 swapCommit?: string; 17 14 validate?: boolean; 18 15 } ··· 20 17 export const createRecord = async <K extends RecordType>(client: Client, options: CreateRecordOptions<K>) => { 21 18 const data = await ok( 22 19 client.post('com.atproto.repo.createRecord', { 23 - input: options, 20 + input: options as any, 24 21 }), 25 22 ); 26 23 ··· 28 25 }; 29 26 30 27 export interface PutRecordOptions<K extends RecordType> { 31 - repo: At.Did; 28 + repo: Did; 32 29 collection: K; 33 30 rkey: string; 34 - record: Records[K]; 31 + record: InferInput<Records[K]>; 35 32 swapCommit?: string; 36 - swapRecord?: At.Cid | null; 33 + swapRecord?: Cid | null; 37 34 validate?: boolean; 38 35 } 39 36 40 37 export const putRecord = async <K extends RecordType>(client: Client, options: PutRecordOptions<K>) => { 41 38 const data = await ok( 42 39 client.post('com.atproto.repo.putRecord', { 43 - input: options, 40 + input: options as any, 44 41 }), 45 42 ); 46 43 ··· 48 45 }; 49 46 50 47 export interface DeleteRecordOptions<K extends RecordType> { 51 - repo: At.Did; 48 + repo: Did; 52 49 collection: K; 53 50 rkey: string; 54 51 swapCommit?: string; ··· 65 62 66 63 export interface GetRecordOptions<K extends RecordType> { 67 64 signal?: AbortSignal; 68 - repo: At.Did; 65 + repo: Did; 69 66 collection: K; 70 67 rkey: string; 71 68 cid?: string; 72 69 } 73 70 74 - export interface GetRecordOutput<T> extends ComAtprotoRepoGetRecord.Output { 71 + export type GetRecordOutput<T> = ComAtprotoRepoGetRecord.$output & { 75 72 value: T; 76 - } 73 + }; 77 74 78 75 export const getRecord = async <K extends RecordType>( 79 76 client: Client, 80 77 options: GetRecordOptions<K>, 81 - ): Promise<GetRecordOutput<Records[K]>> => { 78 + ): Promise<GetRecordOutput<InferInput<Records[K]>>> => { 82 79 const data = await ok( 83 80 client.get('com.atproto.repo.getRecord', { 84 81 signal: options.signal, ··· 96 93 97 94 export interface ListRecordsOptions<K extends RecordType> { 98 95 signal?: AbortSignal; 99 - repo: At.Did; 96 + repo: Did; 100 97 collection: K; 101 98 cursor?: string; 102 99 limit?: number; 103 100 } 104 101 105 - export interface ListRecordsOutput<T> extends ComAtprotoRepoListRecords.Output { 102 + export type ListRecordsOutput<T> = ComAtprotoRepoListRecords.$output & { 106 103 cursor?: string; 107 - records: { cid: At.Cid; uri: At.ResourceUri; value: T }[]; 108 - } 104 + records: { cid: Cid; uri: ResourceUri; value: T }[]; 105 + }; 109 106 110 107 export const listRecords = async <K extends RecordType>( 111 108 client: Client, 112 109 options: ListRecordsOptions<K>, 113 - ): Promise<ListRecordsOutput<Records[K]>> => { 110 + ): Promise<ListRecordsOutput<InferInput<Records[K]>>> => { 114 111 const data = await ok( 115 112 client.get('com.atproto.repo.listRecords', { 116 113 signal: options.signal,
+1 -1
src/api/utils/richtext-stringify.ts
··· 1 + import type { AppBskyRichtextFacet } from '@atcute/bluesky'; 1 2 import { segmentize } from '@atcute/bluesky-richtext-segmenter'; 2 - import type { AppBskyRichtextFacet } from '@atcute/client/lexicons'; 3 3 4 4 import { isLinkValid } from './strings'; 5 5
-17
src/atcute-env.d.ts
··· 1 - import type { AppBskyRichtextFacet } from '@atcute/client/lexicons'; 2 - 3 - declare module '@atcute/client/lexicons' { 4 - namespace AppBskyRichtextFacet { 5 - type FacetFeature = Brand.Union<Link | Mention | Tag | BlueMojiRichtextFacet.Main>; 6 - 7 - interface Main { 8 - features: FacetFeature[]; 9 - } 10 - } 11 - } 12 - 13 - declare module '@atcute/bluesky-richtext-segmenter' { 14 - export interface RichtextSegment { 15 - features: AppBskyRichtextFacet.FacetFeature[] | undefined; 16 - } 17 - }
-73
src/basa-env.d.ts
··· 1 - /* eslint-disable */ 2 - // This file is automatically generated, do not edit! 3 - import '@atcute/client/lexicons'; 4 - 5 - declare module '@atcute/client/lexicons' { 6 - /** Describes the translation proxy instance */ 7 - namespace XBasaDescribeServer { 8 - interface Params {} 9 - type Input = undefined; 10 - interface Output { 11 - engines: Engines; 12 - } 13 - interface Engine { 14 - [Brand.Type]?: 'x.basa.describeServer#engine'; 15 - /** Supported language codes */ 16 - languages: string[]; 17 - } 18 - interface Engines { 19 - [Brand.Type]?: 'x.basa.describeServer#engines'; 20 - deepl?: Engine; 21 - google?: Engine; 22 - } 23 - } 24 - 25 - /** Translates a given text into another language */ 26 - namespace XBasaTranslate { 27 - interface Params { 28 - /** Text needing translation */ 29 - text: string; 30 - /** Target language */ 31 - to: string; 32 - /** 33 - * Which translation service to use 34 - * @default "google" 35 - */ 36 - engine?: 'google' | 'deepl'; 37 - /** 38 - * Source language 39 - * @default "auto" 40 - */ 41 - from?: string; 42 - } 43 - type Input = undefined; 44 - interface Output { 45 - /** Translated text */ 46 - result: string; 47 - /** Deteced language from source text */ 48 - sourceLanguage?: string; 49 - /** Transliteration of source text */ 50 - sourceTransliteration?: string; 51 - /** Transliteration of translated text */ 52 - targetTransliteration?: string; 53 - } 54 - } 55 - 56 - interface Records {} 57 - 58 - interface Queries { 59 - 'x.basa.describeServer': { 60 - response: { json: XBasaDescribeServer.Output }; 61 - /** @deprecated */ 62 - output: XBasaDescribeServer.Output; 63 - }; 64 - 'x.basa.translate': { 65 - params: XBasaTranslate.Params; 66 - response: { json: XBasaTranslate.Output }; 67 - /** @deprecated */ 68 - output: XBasaTranslate.Output; 69 - }; 70 - } 71 - 72 - interface Procedures {} 73 - }
+1 -1
src/components/avatar.tsx
··· 1 1 import { Match, Switch } from 'solid-js'; 2 2 3 - import type { AppBskyActorDefs } from '@atcute/client/lexicons'; 3 + import type { AppBskyActorDefs } from '@atcute/bluesky'; 4 4 5 5 import { type ModerationCause, getModerationUI } from '~/api/moderation'; 6 6 import { ContextProfileMedia, type ModerationContext } from '~/api/moderation/constants';
+1 -1
src/components/bookmarks/add-post-to-folder-dialog.tsx
··· 1 1 import { For, createMemo } from 'solid-js'; 2 2 3 - import type { AppBskyFeedDefs } from '@atcute/client/lexicons'; 3 + import type { AppBskyFeedDefs } from '@atcute/bluesky'; 4 4 import { intersection } from '@mary/array-fns'; 5 5 import { useQueryClient } from '@mary/solid-query'; 6 6
+5 -4
src/components/bookmarks/bookmark-feed-item.tsx
··· 1 1 import { createMemo } from 'solid-js'; 2 2 3 - import type { AppBskyFeedPost } from '@atcute/client/lexicons'; 3 + import type { AppBskyFeedPost } from '@atcute/bluesky'; 4 4 5 5 import { usePostShadow } from '~/api/cache/post-shadow'; 6 6 import { getModerationUI } from '~/api/moderation'; 7 7 import { ContextContentList } from '~/api/moderation/constants'; 8 8 import { moderatePost } from '~/api/moderation/entities/post'; 9 - import { parseCanonicalResourceUri } from '~/api/types/at-uri'; 9 + import { assertCanonicalResourceUri } from '~/api/types/at-uri'; 10 10 11 11 import { history } from '~/globals/navigation'; 12 12 ··· 35 35 const { post, stale } = item; 36 36 37 37 const author = post.author; 38 - const record = post.record as AppBskyFeedPost.Record; 38 + const record = post.record as AppBskyFeedPost.Main; 39 39 const embed = post.embed; 40 40 41 41 const shadow = usePostShadow(post); 42 42 43 - const uri = parseCanonicalResourceUri(post.uri); 43 + const uri = assertCanonicalResourceUri(post.uri); 44 + 44 45 const authorHref = `/${author.did}`; 45 46 const href = `/${author.did}/${uri.rkey}`; 46 47
+1 -1
src/components/composer/composer-dialog.tsx
··· 13 13 } from 'solid-js'; 14 14 import { createMutable, unwrap } from 'solid-js/store'; 15 15 16 - import type { AppBskyActorDefs } from '@atcute/client/lexicons'; 16 + import type { AppBskyActorDefs } from '@atcute/bluesky'; 17 17 import { type CreateQueryResult, useQueryClient } from '@mary/solid-query'; 18 18 19 19 import { GLOBAL_LABELS, getLocalizedLabel } from '~/api/moderation';
+1 -1
src/components/composer/composer-input.tsx
··· 12 12 createSignal, 13 13 } from 'solid-js'; 14 14 15 + import type { AppBskyActorDefs } from '@atcute/bluesky'; 15 16 import { ok } from '@atcute/client'; 16 - import type { AppBskyActorDefs } from '@atcute/client/lexicons'; 17 17 18 18 import { safeUrlParse } from '~/api/utils/strings'; 19 19
+3 -4
src/components/composer/composer-reply-context.tsx
··· 1 1 import { Match, Switch, createMemo } from 'solid-js'; 2 2 3 - import type { AppBskyFeedPost } from '@atcute/client/lexicons'; 3 + import { type AppBskyFeedPost, unwrapMediaEmbed } from '@atcute/bluesky'; 4 4 5 5 import { getModerationUI } from '~/api/moderation'; 6 6 import { ContextContentMedia } from '~/api/moderation/constants'; 7 7 import { moderatePost } from '~/api/moderation/entities/post'; 8 8 import { createPostQuery } from '~/api/queries/post'; 9 - import { unwrapMediaEmbedView } from '~/api/utils/bluesky/embed-view'; 10 9 import { formatQueryError } from '~/api/utils/error'; 11 10 12 11 import { inject } from '~/lib/states/singleton'; ··· 34 33 <Match when={query.data} keyed> 35 34 {(post) => { 36 35 const author = post.author; 37 - const record = post.record as AppBskyFeedPost.Record; 36 + const record = post.record as AppBskyFeedPost.Main; 38 37 39 38 const moderation = createMemo(() => moderatePost(post, moderationOptions())); 40 39 const shouldBlurImage = () => getModerationUI(moderation(), ContextContentMedia).b.length !== 0; 41 40 42 - const media = unwrapMediaEmbedView(post.embed); 41 + const media = unwrapMediaEmbed(post.embed); 43 42 44 43 return ( 45 44 <div class="relative flex gap-3 px-4 pt-3">
+3 -2
src/components/composer/dialogs/composed-interaction-dialog.tsx
··· 1 1 import { For, Match, Switch, batch, createEffect, createMemo, createSignal, untrack } from 'solid-js'; 2 2 3 - import type { AppBskyFeedThreadgate, Brand } from '@atcute/client/lexicons'; 3 + import type { AppBskyFeedThreadgate } from '@atcute/bluesky'; 4 + import type { $type } from '@atcute/lexicons'; 4 5 5 6 import { createMyListsQuery } from '~/api/queries/my-lists'; 6 7 import { dequal } from '~/api/utils/dequal'; ··· 239 240 <Boxed.List> 240 241 <For each={lists.data}> 241 242 {(list) => { 242 - const rule: Brand.Union<AppBskyFeedThreadgate.ListRule> = { 243 + const rule: $type.enforce<AppBskyFeedThreadgate.ListRule> = { 243 244 $type: 'app.bsky.feed.threadgate#listRule', 244 245 list: list.uri, 245 246 };
+1 -1
src/components/composer/embeds/quote-embed.tsx
··· 1 1 import { Match, Switch } from 'solid-js'; 2 2 3 - import type { AppBskyEmbedRecord } from '@atcute/client/lexicons'; 3 + import type { AppBskyEmbedRecord } from '@atcute/bluesky'; 4 4 5 5 import { createPostQuery } from '~/api/queries/post'; 6 6
+3 -3
src/components/composer/gifs/gif-search-dialog.tsx
··· 1 1 import { For, Match, Switch, createSignal } from 'solid-js'; 2 2 3 - import type { At } from '@atcute/client/lexicons'; 3 + import type { GenericUri } from '@atcute/lexicons'; 4 4 import { chunked } from '@mary/array-fns'; 5 5 6 6 import { type Gif, createGifSearchQuery } from '~/api/queries/composer-gif'; ··· 111 111 export default GifSearchDialog; 112 112 113 113 export interface GifMedia { 114 - embedUrl: At.GenericUri; 114 + embedUrl: GenericUri; 115 115 alt: string; 116 116 ratio: { width: number; height: number }; 117 117 ··· 129 129 const [, id, file] = /\/([^/]+?AAAAC)\/([^/]+?)\.gif\/?$/.exec(url)!; 130 130 131 131 return { 132 - embedUrl: (url + `?hh=${dimensions[1]}&ww=${dimensions[0]}`) as At.GenericUri, 132 + embedUrl: (url + `?hh=${dimensions[1]}&ww=${dimensions[0]}`) as GenericUri, 133 133 alt: gif.content_description, 134 134 ratio: { width: dimensions[0], height: dimensions[1] }, 135 135
+33 -32
src/components/composer/lib/api.ts
··· 1 1 import { nanoid } from 'nanoid/non-secure'; 2 2 3 - import { Client, ClientResponseError, ok, simpleFetchHandler } from '@atcute/client'; 3 + import type { 4 + ComAtprotoLabelDefs, 5 + ComAtprotoRepoApplyWrites, 6 + ComAtprotoRepoStrongRef, 7 + } from '@atcute/atproto'; 8 + import type { BlueMojiRichtextFacet } from '@atcute/bluemoji'; 4 9 import type { 5 10 AppBskyEmbedImages, 6 11 AppBskyEmbedRecord, ··· 12 17 AppBskyGraphDefs, 13 18 AppBskyRichtextFacet, 14 19 AppBskyVideoDefs, 15 - At, 16 - BlueMojiRichtextFacet, 17 - Brand, 18 - ComAtprotoLabelDefs, 19 - ComAtprotoRepoApplyWrites, 20 - ComAtprotoRepoStrongRef, 21 - } from '@atcute/client/lexicons'; 20 + } from '@atcute/bluesky'; 21 + import { Client, ClientResponseError, ok, simpleFetchHandler } from '@atcute/client'; 22 + import { type $type, type Blob as AtpBlob, type Did, type GenericUri, type Handle } from '@atcute/lexicons'; 22 23 import * as TID from '@atcute/tid'; 23 24 import type { QueryClient } from '@mary/solid-query'; 24 25 ··· 26 27 import { uploadBlob } from '~/api/queries/blob'; 27 28 import type { LinkMeta } from '~/api/queries/composer'; 28 29 import { resolveHandle } from '~/api/queries/handle'; 29 - import { makeAtUri, parseCanonicalResourceUri } from '~/api/types/at-uri'; 30 + import { assertCanonicalResourceUri, makeAtUri } from '~/api/types/at-uri'; 30 31 import { isDid } from '~/api/types/identity'; 31 32 import { getRecord } from '~/api/utils/records'; 32 33 import { trimRichText } from '~/api/utils/richtext'; ··· 61 62 const did = agent.did!; 62 63 63 64 const now = new Date(); 64 - const writes: ComAtprotoRepoApplyWrites.Input['writes'] = []; 65 + const writes: ComAtprotoRepoApplyWrites.$input['writes'] = []; 65 66 66 67 let reply: AppBskyFeedPost.ReplyRef | undefined; 67 68 let rkey: string | undefined; ··· 74 75 queryKey: ['post', replyUri], 75 76 staleTime: 30_000, 76 77 async queryFn(ctx) { 77 - const uri = parseCanonicalResourceUri(replyUri); 78 + const uri = assertCanonicalResourceUri(replyUri); 78 79 79 - let did: At.Did; 80 + let did: Did; 80 81 if (isDid(uri.repo)) { 81 82 did = uri.repo; 82 83 } else { ··· 102 103 }, 103 104 }); 104 105 105 - const root = (post.record as AppBskyFeedPost.Record).reply?.root; 106 + const root = (post.record as AppBskyFeedPost.Main).reply?.root; 106 107 const ref: ComAtprotoRepoStrongRef.Main = { 107 108 uri: post.uri, 108 109 cid: post.cid, ··· 115 116 } 116 117 117 118 if (state.redraftUri) { 118 - const uri = parseCanonicalResourceUri(state.redraftUri); 119 + const uri = assertCanonicalResourceUri(state.redraftUri); 119 120 120 121 writes.push({ 121 122 $type: 'com.atproto.repo.applyWrites#delete', ··· 141 142 142 143 // Get the self-labels 143 144 const labels = getEmbedLabels(post.embed); 144 - let selfLabels: Brand.Union<ComAtprotoLabelDefs.SelfLabels> | undefined; 145 + let selfLabels: $type.enforce<ComAtprotoLabelDefs.SelfLabels> | undefined; 145 146 146 147 if (labels?.length) { 147 148 selfLabels = { ··· 151 152 } 152 153 153 154 // Now form the record 154 - const record: AppBskyFeedPost.Record = { 155 + const record: AppBskyFeedPost.Main = { 155 156 $type: 'app.bsky.feed.post', 156 157 createdAt: now.toISOString(), 157 158 text: rt.text, ··· 171 172 172 173 // If this is the first post, and we have a threadgate set, create one now. 173 174 if (idx === 0 && !reply && state.threadgate.allow) { 174 - const threadgateRecord: AppBskyFeedThreadgate.Record = { 175 + const threadgateRecord: AppBskyFeedThreadgate.Main = { 175 176 $type: 'app.bsky.feed.threadgate', 176 177 createdAt: now.toISOString(), 177 178 post: uri, ··· 188 189 189 190 // If we have a postgate set, create one for this post. 190 191 if (state.postgate.embeddingRules?.length) { 191 - const postgateRecord: AppBskyFeedPostgate.Record = { 192 + const postgateRecord: AppBskyFeedPostgate.Main = { 192 193 $type: 'app.bsky.feed.postgate', 193 194 createdAt: now.toISOString(), 194 195 post: uri, ··· 243 244 244 245 return writes; 245 246 246 - async function resolveEmbed(root: PostEmbed): Promise<AppBskyFeedPost.Record['embed']> { 247 + async function resolveEmbed(root: PostEmbed): Promise<AppBskyFeedPost.Main['embed']> { 247 248 let pMedia: Promise<AppBskyEmbedRecordWithMedia.Main['media']> | undefined; 248 - let pRecord: Promise<Brand.Union<AppBskyEmbedRecord.Main>> | undefined; 249 + let pRecord: Promise<$type.enforce<AppBskyEmbedRecord.Main>> | undefined; 249 250 250 251 if (root.media) { 251 252 pMedia = resolveMediaEmbed(root.media); ··· 477 478 } 478 479 479 480 // Check the upload status 480 - let result: At.Blob<any>; 481 + let result: AtpBlob<any>; 481 482 { 482 483 let pollFailures = 0; 483 484 ··· 509 510 const state = status.state; 510 511 511 512 if (state === 'JOB_STATE_COMPLETED') { 512 - if (!status.blob) { 513 + if (!status.blob || !('$type' in status.blob)) { 513 514 throw new PublishError(`Unexpected error when processing video`); 514 515 } 515 516 ··· 547 548 const gif = embed.gif; 548 549 const alt = embed.alt; 549 550 550 - let thumbBlob: At.Blob<any> | undefined; 551 + let thumbBlob: AtpBlob<any> | undefined; 551 552 552 553 { 553 554 log?.(`Retrieving GIF thumbnail`); ··· 592 593 593 594 // compress... upload... 594 595 const thumb = meta.thumb; 595 - let thumbBlob: At.Blob<any> | undefined; 596 + let thumbBlob: AtpBlob<any> | undefined; 596 597 597 598 if (thumb !== undefined) { 598 599 log?.(`Uploading link thumbnail`); ··· 616 617 617 618 async function resolveRecordEmbed( 618 619 record: PostRecordEmbed, 619 - ): Promise<Brand.Union<AppBskyEmbedRecord.Main>> { 620 + ): Promise<$type.enforce<AppBskyEmbedRecord.Main>> { 620 621 const type = record.type; 621 622 622 623 if (type === 'feed') { ··· 683 684 if (type === 'link' || type === 'autolink') { 684 685 facets.push({ 685 686 index: index, 686 - features: [{ $type: 'app.bsky.richtext.facet#link', uri: token.url as At.GenericUri }], 687 + features: [{ $type: 'app.bsky.richtext.facet#link', uri: token.url as GenericUri }], 687 688 }); 688 689 } else if (type === 'mention') { 689 - const handle = token.handle as At.Handle; 690 + const handle = token.handle as Handle; 690 691 691 692 if (handle === 'handle.invalid') { 692 693 throw new InvalidHandleError(handle); ··· 735 736 736 737 const raws = value.formats; 737 738 738 - const cids: Brand.Union<BlueMojiRichtextFacet.Formats_v0> = { 739 + const cids: $type.enforce<BlueMojiRichtextFacet.Formats_v0> = { 739 740 $type: 'blue.moji.richtext.facet#formats_v0', 740 741 }; 741 742 ··· 748 749 cids.lottie = true; 749 750 } 750 751 751 - if (raws.gif_128) { 752 + if (raws.gif_128 && '$type' in raws.gif_128) { 752 753 cids.gif_128 = raws.gif_128.ref.$link; 753 754 } 754 755 755 - if (raws.png_128) { 756 + if (raws.png_128 && '$type' in raws.png_128) { 756 757 cids.png_128 = raws.png_128.ref.$link; 757 758 } 758 759 759 - if (raws.webp_128) { 760 + if (raws.webp_128 && '$type' in raws.webp_128) { 760 761 cids.webp_128 = raws.webp_128.ref.$link; 761 762 } 762 763 } 763 764 764 - const facet: Brand.Union<BlueMojiRichtextFacet.Main> = { 765 + const facet: $type.enforce<BlueMojiRichtextFacet.Main> = { 765 766 $type: 'blue.moji.richtext.facet', 766 767 did: did, 767 768 name: value.name,
+4 -9
src/components/composer/lib/state.tsx
··· 1 1 import { unwrap } from 'solid-js/store'; 2 2 3 - import type { 4 - AppBskyEmbedDefs, 5 - AppBskyEmbedExternal, 6 - AppBskyFeedDefs, 7 - At, 8 - Brand, 9 - } from '@atcute/client/lexicons'; 3 + import type { AppBskyEmbedDefs, AppBskyEmbedExternal, AppBskyFeedDefs } from '@atcute/bluesky'; 4 + import type { $type, Blob as AtpBlob } from '@atcute/lexicons'; 10 5 11 6 import { primarySystemLanguage } from '~/globals/locales'; 12 7 ··· 38 33 39 34 export interface RemoteMediaSource { 40 35 type: 'remote'; 41 - blob: At.Blob; 36 + blob: AtpBlob; 42 37 aspectRatio?: AppBskyEmbedDefs.AspectRatio; 43 38 } 44 39 ··· 89 84 90 85 export interface RemoteLinkSource { 91 86 type: 'remote'; 92 - state: Brand.Union<AppBskyEmbedExternal.Main>; 87 + state: $type.enforce<AppBskyEmbedExternal.Main>; 93 88 } 94 89 95 90 export type LinkSource = UriLinkSource | RemoteLinkSource;
+6 -7
src/components/embeds/embed.tsx
··· 1 - import type { AppBskyFeedDefs } from '@atcute/client/lexicons'; 1 + import { type AppBskyFeedDefs, type MediaEmbed, type RecordEmbed, unwrapEmbed } from '@atcute/bluesky'; 2 2 3 3 import { type ModerationCause, getModerationUI } from '~/api/moderation'; 4 4 import { ContextContentMedia } from '~/api/moderation/constants'; 5 - import { parseCanonicalResourceUri } from '~/api/types/at-uri'; 6 - import { type MediaEmbedView, type RecordEmbedView, unwrapEmbedView } from '~/api/utils/bluesky/embed-view'; 5 + import { assertCanonicalResourceUri } from '~/api/types/at-uri'; 7 6 8 7 import ContentHider from '../moderation/content-hider'; 9 8 ··· 26 25 } 27 26 28 27 const Embed = (props: EmbedProps) => { 29 - const { media, record } = unwrapEmbedView(props.embed); 28 + const { media, record } = unwrapEmbed(props.embed); 30 29 31 30 const gutterTop = props.gutterTop; 32 31 const large = props.large; ··· 43 42 44 43 interface MediaEmbedProps { 45 44 /** Expected to be static */ 46 - embed: MediaEmbedView; 45 + embed: MediaEmbed; 47 46 moderation?: ModerationCause[]; 48 47 } 49 48 ··· 76 75 77 76 interface RecordEmbedProps { 78 77 /** Expected to be static */ 79 - embed: RecordEmbedView; 78 + embed: RecordEmbed; 80 79 /** Expected to be static */ 81 80 large?: boolean; 82 81 } ··· 100 99 } 101 100 102 101 if (type === 'app.bsky.embed.record#viewNotFound' || type === 'app.bsky.embed.record#viewBlocked') { 103 - const uri = parseCanonicalResourceUri(embed.uri); 102 + const uri = assertCanonicalResourceUri(embed.uri); 104 103 105 104 if (type === 'app.bsky.embed.record#viewBlocked' && uri.collection === 'app.bsky.feed.post') { 106 105 return <QuoteBlockedEmbed embed={embed} uri={uri} />;
+1 -1
src/components/embeds/external-embed.tsx
··· 1 1 import { type JSX, createSignal } from 'solid-js'; 2 2 3 - import type { AppBskyEmbedExternal } from '@atcute/client/lexicons'; 3 + import type { AppBskyEmbedExternal } from '@atcute/bluesky'; 4 4 5 5 import { safeUrlParse } from '~/api/utils/strings'; 6 6
+3 -3
src/components/embeds/feed-embed.tsx
··· 1 1 import { createMemo } from 'solid-js'; 2 2 3 - import type { AppBskyFeedDefs } from '@atcute/client/lexicons'; 3 + import type { AppBskyFeedDefs } from '@atcute/bluesky'; 4 4 import { useQueryClient } from '@mary/solid-query'; 5 5 6 6 import { moderateGeneric } from '~/api/moderation/entities/generic'; 7 7 import { precacheFeed } from '~/api/queries-cache/feed-precache'; 8 - import { parseCanonicalResourceUri } from '~/api/types/at-uri'; 8 + import { assertCanonicalResourceUri } from '~/api/types/at-uri'; 9 9 10 10 import { inject } from '~/lib/states/singleton'; 11 11 import ModerationService from '~/lib/states/singletons/moderation'; ··· 26 26 27 27 const moderation = createMemo(() => moderateGeneric(feed, feed.creator.did, moderationOptions())); 28 28 29 - const href = `/${feed.creator.did}/feeds/${parseCanonicalResourceUri(feed.uri).rkey}`; 29 + const href = `/${feed.creator.did}/feeds/${assertCanonicalResourceUri(feed.uri).rkey}`; 30 30 31 31 return ( 32 32 <a
+1 -1
src/components/embeds/image-grid-embed.tsx
··· 1 - import type { AppBskyEmbedImages } from '@atcute/client/lexicons'; 1 + import type { AppBskyEmbedImages } from '@atcute/bluesky'; 2 2 3 3 export interface ImageGridEmbedProps { 4 4 /** Expected to be static */
+1 -1
src/components/embeds/image-standalone-embed.tsx
··· 1 - import type { AppBskyEmbedImages } from '@atcute/client/lexicons'; 1 + import type { AppBskyEmbedImages } from '@atcute/bluesky'; 2 2 3 3 import { openModal } from '~/globals/modals'; 4 4
+1 -1
src/components/embeds/lib/image-utils.ts
··· 1 - import type { AppBskyEmbedImages } from '@atcute/client/lexicons'; 1 + import type { AppBskyEmbedImages } from '@atcute/bluesky'; 2 2 3 3 const clamp = (value: number, min: number, max: number): number => { 4 4 return Math.max(min, Math.min(max, value));
+1 -1
src/components/embeds/lib/snippet.tsx
··· 1 - import type { AppBskyEmbedExternal } from '@atcute/client/lexicons'; 1 + import type { AppBskyEmbedExternal } from '@atcute/bluesky'; 2 2 3 3 import { safeUrlParse } from '~/api/utils/strings'; 4 4
+1 -1
src/components/embeds/list-embed.tsx
··· 1 1 import { createMemo } from 'solid-js'; 2 2 3 - import type { AppBskyGraphDefs } from '@atcute/client/lexicons'; 3 + import type { AppBskyGraphDefs } from '@atcute/bluesky'; 4 4 5 5 import { moderateGeneric } from '~/api/moderation/entities/generic'; 6 6
+1 -1
src/components/embeds/players/video-player.tsx
··· 3 3 import { nanoid } from 'nanoid/non-secure'; 4 4 import { createEffect, createSignal, onCleanup } from 'solid-js'; 5 5 6 - import type { AppBskyEmbedVideo } from '@atcute/client/lexicons'; 6 + import type { AppBskyEmbedVideo } from '@atcute/bluesky'; 7 7 8 8 import { globalEvents } from '~/globals/events'; 9 9
+2 -3
src/components/embeds/quote-blocked-embed.tsx
··· 1 - import type { AppBskyEmbedRecord } from '@atcute/client/lexicons'; 2 - 3 - import type { ParsedCanonicalResourceUri } from '~/api/types/at-uri'; 1 + import type { AppBskyEmbedRecord } from '@atcute/bluesky'; 2 + import type { ParsedCanonicalResourceUri } from '@atcute/lexicons'; 4 3 5 4 import BlockOutlinedIcon from '../icons-central/block-outline'; 6 5
+5 -6
src/components/embeds/quote-embed.tsx
··· 1 1 import { type JSX, createMemo } from 'solid-js'; 2 2 3 - import type { AppBskyEmbedRecord, AppBskyFeedPost } from '@atcute/client/lexicons'; 3 + import { AppBskyEmbedRecord, AppBskyFeedPost, unwrapMediaEmbed } from '@atcute/bluesky'; 4 4 5 5 import { getModerationUI } from '~/api/moderation'; 6 6 import { ContextContentMedia } from '~/api/moderation/constants'; 7 7 import { moderateQuote } from '~/api/moderation/entities/quote'; 8 - import { parseCanonicalResourceUri } from '~/api/types/at-uri'; 9 - import { unwrapMediaEmbedView } from '~/api/utils/bluesky/embed-view'; 8 + import { assertCanonicalResourceUri } from '~/api/types/at-uri'; 10 9 11 10 import { inject } from '~/lib/states/singleton'; 12 11 import ModerationService from '~/lib/states/singletons/moderation'; ··· 29 28 const QuoteEmbed = ({ quote, interactive, large }: QuoteEmbedProps) => { 30 29 const moderationOptions = inject(ModerationService); 31 30 32 - const record = quote.value as AppBskyFeedPost.Record; 31 + const record = quote.value as AppBskyFeedPost.Main; 33 32 const author = quote.author; 34 33 35 - const uri = parseCanonicalResourceUri(quote.uri); 34 + const uri = assertCanonicalResourceUri(quote.uri); 36 35 const href = `/${author.did}/${uri.rkey}`; 37 36 38 37 const text = record.text.trim(); 39 - const media = unwrapMediaEmbedView(quote.embeds?.[0]); 38 + const media = unwrapMediaEmbed(quote.embeds?.[0]); 40 39 41 40 const moderation = createMemo(() => moderateQuote(quote, moderationOptions())); 42 41
+1 -1
src/components/embeds/video-embed.tsx
··· 1 1 import { Show, Suspense, createSignal, lazy } from 'solid-js'; 2 2 3 - import type { AppBskyEmbedDefs, AppBskyEmbedVideo } from '@atcute/client/lexicons'; 3 + import { AppBskyEmbedDefs, AppBskyEmbedVideo } from '@atcute/bluesky'; 4 4 5 5 import { replaceVideoCdnUrl } from '~/lib/bsky/video'; 6 6
+1 -1
src/components/error-view.tsx
··· 1 1 import { Match, Switch } from 'solid-js'; 2 2 3 + import type { AppBskyActorDefs } from '@atcute/bluesky'; 3 4 import { ClientResponseError } from '@atcute/client'; 4 - import type { AppBskyActorDefs } from '@atcute/client/lexicons'; 5 5 import { TokenRefreshError } from '@atcute/oauth-browser-client'; 6 6 import { useQueryClient } from '@mary/solid-query'; 7 7
+3 -3
src/components/explore/my-feeds-section.tsx
··· 1 1 import { For, createMemo } from 'solid-js'; 2 2 3 - import { parseCanonicalResourceUri } from '~/api/types/at-uri'; 3 + import { assertCanonicalResourceUri } from '~/api/types/at-uri'; 4 4 5 5 import type { SavedFeed } from '~/lib/preferences/account'; 6 6 import { useSession } from '~/lib/states/session'; ··· 55 55 let href: string; 56 56 switch (type) { 57 57 case 'generator': { 58 - const uri = parseCanonicalResourceUri(feed.info.uri); 58 + const uri = assertCanonicalResourceUri(feed.info.uri); 59 59 href = `/${uri.repo}/feeds/${uri.rkey}`; 60 60 break; 61 61 } 62 62 case 'list': { 63 - const uri = parseCanonicalResourceUri(feed.info.uri); 63 + const uri = assertCanonicalResourceUri(feed.info.uri); 64 64 href = `/${uri.repo}/lists/${uri.rkey}`; 65 65 break; 66 66 }
+3 -3
src/components/feeds/feed-info-prompt.tsx
··· 1 - import type { AppBskyFeedDefs } from '@atcute/client/lexicons'; 1 + import type { AppBskyFeedDefs } from '@atcute/bluesky'; 2 2 3 - import { parseCanonicalResourceUri } from '~/api/types/at-uri'; 3 + import { assertCanonicalResourceUri } from '~/api/types/at-uri'; 4 4 5 5 import { useModalContext } from '~/globals/modals'; 6 6 ··· 20 20 const feed = props.feed; 21 21 22 22 const authorUrl = `/${feed.creator.did}`; 23 - const feedUrl = `${authorUrl}/feeds/${parseCanonicalResourceUri(feed.uri).rkey}`; 23 + const feedUrl = `${authorUrl}/feeds/${assertCanonicalResourceUri(feed.uri).rkey}`; 24 24 25 25 return ( 26 26 <Prompt.Container maxWidth="md">
+3 -3
src/components/feeds/feed-item.tsx
··· 1 1 import { createMemo } from 'solid-js'; 2 2 3 - import type { AppBskyFeedDefs } from '@atcute/client/lexicons'; 3 + import type { AppBskyFeedDefs } from '@atcute/bluesky'; 4 4 import { useQueryClient } from '@mary/solid-query'; 5 5 6 6 import { moderateGeneric } from '~/api/moderation/entities/generic'; 7 7 import { precacheFeed } from '~/api/queries-cache/feed-precache'; 8 - import { parseCanonicalResourceUri } from '~/api/types/at-uri'; 8 + import { assertCanonicalResourceUri } from '~/api/types/at-uri'; 9 9 10 10 import { history } from '~/globals/navigation'; 11 11 ··· 27 27 const moderationOptions = inject(ModerationService); 28 28 29 29 const creator = item.creator; 30 - const href = `/${creator.did}/feeds/${parseCanonicalResourceUri(item.uri).rkey}`; 30 + const href = `/${creator.did}/feeds/${assertCanonicalResourceUri(item.uri).rkey}`; 31 31 32 32 const moderation = createMemo(() => moderateGeneric(item, creator.did, moderationOptions())); 33 33
+4 -3
src/components/feeds/feed-overflow-menu.tsx
··· 1 1 import { createMemo } from 'solid-js'; 2 2 3 - import type { AppBskyFeedDefs } from '@atcute/client/lexicons'; 3 + import type { AppBskyFeedDefs } from '@atcute/bluesky'; 4 4 5 - import { parseCanonicalResourceUri } from '~/api/types/at-uri'; 5 + import { assertCanonicalResourceUri } from '~/api/types/at-uri'; 6 6 7 7 import { useModalContext } from '~/globals/modals'; 8 8 ··· 83 83 icon={OpenInNewOutlinedIcon} 84 84 label="Open in Bluesky app" 85 85 onClick={() => { 86 - const uri = `https://bsky.app/profile/${feed.creator.did}/feed/${parseCanonicalResourceUri(feed.uri).rkey}`; 86 + const { repo, rkey } = assertCanonicalResourceUri(feed.uri); 87 + const uri = `https://bsky.app/profile/${repo}/feed/${rkey}`; 87 88 88 89 close(); 89 90 window.open(uri, '_blank');
+3 -3
src/components/lists/lib/utils.ts
··· 1 - import type { AppBskyGraphDefs } from '@atcute/client/lexicons'; 1 + import type { AppBskyGraphDefs } from '@atcute/bluesky'; 2 2 3 - import { parseCanonicalResourceUri } from '~/api/types/at-uri'; 3 + import { assertCanonicalResourceUri } from '~/api/types/at-uri'; 4 4 5 5 export const getListPurposeLabel = (purpose: AppBskyGraphDefs.ListPurpose) => { 6 6 switch (purpose) { ··· 15 15 16 16 export const getListUrl = (list: AppBskyGraphDefs.ListView) => { 17 17 const did = list.creator.did; 18 - const { rkey } = parseCanonicalResourceUri(list.uri); 18 + const { rkey } = assertCanonicalResourceUri(list.uri); 19 19 20 20 switch (list.purpose) { 21 21 case 'app.bsky.graph.defs#curatelist':
+1 -1
src/components/lists/list-item.tsx
··· 1 1 import { createMemo } from 'solid-js'; 2 2 3 - import type { AppBskyGraphDefs } from '@atcute/client/lexicons'; 3 + import type { AppBskyGraphDefs } from '@atcute/bluesky'; 4 4 import { useQueryClient } from '@mary/solid-query'; 5 5 6 6 import { moderateGeneric } from '~/api/moderation/entities/generic';
+2 -2
src/components/main/sign-in-dialog.tsx
··· 1 1 import { Match, Switch, createSignal, onMount } from 'solid-js'; 2 2 3 - import type { At } from '@atcute/client/lexicons'; 3 + import type { Did } from '@atcute/lexicons'; 4 4 import { 5 5 type AuthorizationServerMetadata, 6 6 type IdentityMetadata, ··· 27 27 } 28 28 29 29 export interface SignInDialogProps { 30 - relogin?: { did: At.Did; handle?: string }; 30 + relogin?: { did: Did; handle?: string }; 31 31 } 32 32 33 33 const SignInDialog = (props: SignInDialogProps) => {
+7 -6
src/components/moderation/block-account-prompt.tsx
··· 1 1 import { Match, Switch } from 'solid-js'; 2 2 3 - import type { AppBskyActorDefs, At } from '@atcute/client/lexicons'; 3 + import type { AppBskyActorDefs } from '@atcute/bluesky'; 4 + import { type Did } from '@atcute/lexicons'; 4 5 import { QueryClient, createMutation } from '@mary/solid-query'; 5 6 6 7 import { type ProfileShadowView, updateProfileShadow, useProfileShadow } from '~/api/cache/profile-shadow'; 7 8 import { createListMetaQuery } from '~/api/queries/list'; 8 - import { parseCanonicalResourceUri } from '~/api/types/at-uri'; 9 + import { assertCanonicalResourceUri } from '~/api/types/at-uri'; 9 10 import { getCurrentDate } from '~/api/utils/misc'; 10 11 import { createRecord, deleteRecord } from '~/api/utils/records'; 11 12 ··· 132 133 133 134 const mutation = createMutation((queryClient) => ({ 134 135 async mutationFn() { 135 - const { repo, rkey } = parseCanonicalResourceUri(props.shadow.blockUri!); 136 + const uri = assertCanonicalResourceUri(props.shadow.blockUri!); 136 137 137 138 return await deleteRecord(client, { 138 - repo: repo as At.Did, 139 + repo: uri.repo, 139 140 collection: 'app.bsky.graph.block', 140 - rkey: rkey, 141 + rkey: uri.rkey, 141 142 }); 142 143 }, 143 144 onSuccess() { ··· 228 229 ); 229 230 }; 230 231 231 - const resetThreadQueries = (queryClient: QueryClient, did: At.Did) => { 232 + const resetThreadQueries = (queryClient: QueryClient, did: Did) => { 232 233 const substring = `at://${did}/`; 233 234 234 235 queryClient.resetQueries({
+1 -1
src/components/moderation/labels-on-me.tsx
··· 1 1 import { Show } from 'solid-js'; 2 2 3 - import type { ComAtprotoLabelDefs } from '@atcute/client/lexicons'; 3 + import type { ComAtprotoLabelDefs } from '@atcute/atproto'; 4 4 5 5 import { useSession } from '~/lib/states/session'; 6 6
+1 -1
src/components/moderation/mute-account-prompt.tsx
··· 1 1 import { Match, Switch, onMount } from 'solid-js'; 2 2 3 + import type { AppBskyActorDefs } from '@atcute/bluesky'; 3 4 import { ok } from '@atcute/client'; 4 - import type { AppBskyActorDefs } from '@atcute/client/lexicons'; 5 5 import { createMutation } from '@mary/solid-query'; 6 6 7 7 import { updateProfileShadow, useProfileShadow } from '~/api/cache/profile-shadow';
+15 -13
src/components/notifications/notification-item.tsx
··· 1 1 import { type Component, type ComponentProps, type JSX, createMemo } from 'solid-js'; 2 2 3 - import type { 4 - AppBskyEmbedImages, 5 - AppBskyFeedDefs, 6 - AppBskyFeedPost, 7 - AppBskyNotificationListNotifications, 8 - } from '@atcute/client/lexicons'; 3 + import { 4 + type AppBskyEmbedImages, 5 + type AppBskyFeedDefs, 6 + type AppBskyFeedPost, 7 + type AppBskyNotificationListNotifications, 8 + type MediaEmbed, 9 + unwrapMediaEmbed, 10 + } from '@atcute/bluesky'; 9 11 import { useQueryClient } from '@mary/solid-query'; 10 12 11 13 import { getModerationUI } from '~/api/moderation'; ··· 19 21 NotificationSlice, 20 22 RepostNotificationSlice, 21 23 } from '~/api/queries/notification-feed'; 22 - import { parseCanonicalResourceUri } from '~/api/types/at-uri'; 23 - import { type MediaEmbedView, unwrapMediaEmbedView } from '~/api/utils/bluesky/embed-view'; 24 + import { assertCanonicalResourceUri } from '~/api/types/at-uri'; 24 25 25 26 import { history } from '~/globals/navigation'; 26 27 ··· 95 96 } 96 97 } else { 97 98 const post = item.view; 98 - const uri = parseCanonicalResourceUri(post.uri); 99 - href = `/${uri.repo}/${uri.rkey}`; 99 + const { repo, rkey } = assertCanonicalResourceUri(post.uri); 100 + 101 + href = `/${repo}/${rkey}`; 100 102 } 101 103 102 104 if (isElementAltClicked(ev)) { ··· 234 236 235 237 if (type === 'like' || type === 'repost') { 236 238 const post = data.view; 237 - const record = post.record as AppBskyFeedPost.Record; 239 + const record = post.record as AppBskyFeedPost.Main; 238 240 239 - const media = unwrapMediaEmbedView(post.embed); 241 + const media = unwrapMediaEmbed(post.embed); 240 242 const gif = maybeUnwrapGifEmbed(media); 241 243 242 244 return ( ··· 300 302 ); 301 303 }; 302 304 303 - const maybeUnwrapGifEmbed = (embed: MediaEmbedView | undefined): BlueskyGifSnippet | undefined => { 305 + const maybeUnwrapGifEmbed = (embed: MediaEmbed | undefined): BlueskyGifSnippet | undefined => { 304 306 if (embed?.$type === 'app.bsky.embed.external#view') { 305 307 const snippet = detectSnippet(embed.external); 306 308 if (snippet.type !== SnippetType.BLUESKY_GIF) {
+4 -3
src/components/profiles/edit-profile-dialog.tsx
··· 1 1 import { Show, createMemo, createSignal } from 'solid-js'; 2 2 3 + import type { AppBskyActorDefs } from '@atcute/bluesky'; 3 4 import { ClientResponseError } from '@atcute/client'; 4 - import type { AppBskyActorDefs, At } from '@atcute/client/lexicons'; 5 + import type { Blob as AtpBlob } from '@atcute/lexicons'; 5 6 import { createMutation } from '@mary/solid-query'; 6 7 7 8 import { uploadBlob } from '~/api/queries/blob'; ··· 74 75 const $avatar = avatar(); 75 76 const $banner = banner(); 76 77 77 - let avatarPromise: Promise<At.Blob<any>> | undefined; 78 - let bannerPromise: Promise<At.Blob<any>> | undefined; 78 + let avatarPromise: Promise<AtpBlob<any>> | undefined; 79 + let bannerPromise: Promise<AtpBlob<any>> | undefined; 79 80 80 81 if ($avatar instanceof Blob) { 81 82 avatarPromise = compressProfileImage($avatar, 1000, 1000).then((res) => uploadBlob(client, res.blob));
+1 -1
src/components/profiles/handle-overflow-menu.tsx
··· 1 - import type { AppBskyActorDefs } from '@atcute/client/lexicons'; 1 + import type { AppBskyActorDefs } from '@atcute/bluesky'; 2 2 3 3 import { useModalContext } from '~/globals/modals'; 4 4
+1 -1
src/components/profiles/profile-follow-button.tsx
··· 1 1 import { type JSX, createMemo } from 'solid-js'; 2 2 3 - import type { AppBskyActorDefs } from '@atcute/client/lexicons'; 3 + import type { AppBskyActorDefs } from '@atcute/bluesky'; 4 4 5 5 import { useProfileShadow } from '~/api/cache/profile-shadow'; 6 6 import { createProfileFollowMutation } from '~/api/mutations/profile';
+1 -1
src/components/profiles/profile-item-pressable.tsx
··· 1 1 import { type JSX, createMemo } from 'solid-js'; 2 2 3 - import type { AppBskyActorDefs } from '@atcute/client/lexicons'; 3 + import type { AppBskyActorDefs } from '@atcute/bluesky'; 4 4 5 5 import { moderateProfile } from '~/api/moderation/entities/profile'; 6 6
+1 -1
src/components/profiles/profile-item.tsx
··· 1 1 import { type JSX, createMemo } from 'solid-js'; 2 2 3 - import type { AppBskyActorDefs } from '@atcute/client/lexicons'; 3 + import type { AppBskyActorDefs } from '@atcute/bluesky'; 4 4 import { useQueryClient } from '@mary/solid-query'; 5 5 6 6 import { moderateProfile } from '~/api/moderation/entities/profile';
+1 -1
src/components/profiles/profile-overflow-menu.tsx
··· 1 1 import { createMemo } from 'solid-js'; 2 2 3 - import type { AppBskyActorDefs } from '@atcute/client/lexicons'; 3 + import type { AppBskyActorDefs } from '@atcute/bluesky'; 4 4 5 5 import { useProfileShadow } from '~/api/cache/profile-shadow'; 6 6
+4 -4
src/components/profiles/profile-view-header.tsx
··· 1 1 import { type Component, type ComponentProps, type JSX, Match, Show, Switch, createMemo } from 'solid-js'; 2 2 3 - import type { AppBskyActorDefs } from '@atcute/client/lexicons'; 3 + import type { AppBskyActorDefs } from '@atcute/bluesky'; 4 4 5 5 import { useProfileShadow } from '~/api/cache/profile-shadow'; 6 6 import { getModerationUI } from '~/api/moderation'; 7 7 import { ContextProfileMedia, ContextProfileView } from '~/api/moderation/constants'; 8 8 import { moderateProfile } from '~/api/moderation/entities/profile'; 9 - import { parseCanonicalResourceUri } from '~/api/types/at-uri'; 9 + import { assertCanonicalResourceUri } from '~/api/types/at-uri'; 10 10 11 11 import { openModal } from '~/globals/modals'; 12 12 ··· 259 259 <Match when={viewer()?.mutedByList}> 260 260 {(list) => { 261 261 const href = () => { 262 - const uri = parseCanonicalResourceUri(list().uri); 263 - return `/${uri.repo}/lists/${uri.rkey}`; 262 + const { repo, rkey } = assertCanonicalResourceUri(list().uri); 263 + return `/${repo}/lists/${rkey}`; 264 264 }; 265 265 266 266 return (
+6 -4
src/components/rich-text.tsx
··· 1 1 import type { JSX } from 'solid-js'; 2 2 3 + import type { BlueMojiRichtextFacet } from '@atcute/bluemoji'; 4 + import type { AppBskyRichtextFacet } from '@atcute/bluesky'; 3 5 import { segmentize } from '@atcute/bluesky-richtext-segmenter'; 4 - import type { AppBskyRichtextFacet } from '@atcute/client/lexicons'; 5 6 6 7 import { isLinkValid } from '~/api/utils/strings'; 7 8 ··· 64 65 65 66 break; 66 67 } else if (type === 'blue.moji.richtext.facet') { 67 - const formats = feature.formats; 68 + const feat = feature as BlueMojiRichtextFacet.Main; 69 + const formats = feat.formats; 68 70 if (formats.$type !== 'blue.moji.richtext.facet#formats_v0' || !formats.png_128) { 69 71 continue; 70 72 } 71 73 72 74 node = ( 73 75 <img 74 - src={/* @once */ getCdnUrl(feature.did, formats.png_128)} 75 - title={/* @once */ feature.name} 76 + src={/* @once */ getCdnUrl(feat.did, formats.png_128)} 77 + title={/* @once */ feat.name} 76 78 class={`mx-px inline-block align-top text-[0]` + (!large ? ` h-5 w-5` : ` h-6 w-6`)} 77 79 /> 78 80 );
+7 -7
src/components/threads/highlighted-post.tsx
··· 1 1 import { Show, createMemo } from 'solid-js'; 2 2 3 - import type { AppBskyFeedDefs, AppBskyFeedPost } from '@atcute/client/lexicons'; 3 + import { AppBskyFeedDefs, AppBskyFeedPost } from '@atcute/bluesky'; 4 4 5 5 import { usePostShadow } from '~/api/cache/post-shadow'; 6 6 import { getModerationUI } from '~/api/moderation'; 7 7 import { ContextContentView } from '~/api/moderation/constants'; 8 8 import { moderatePost } from '~/api/moderation/entities/post'; 9 9 import { createPostLikeMutation, createPostRepostMutation } from '~/api/mutations/post'; 10 - import { parseCanonicalResourceUri } from '~/api/types/at-uri'; 10 + import { assertCanonicalResourceUri } from '~/api/types/at-uri'; 11 11 12 12 import { primarySystemLanguage } from '~/globals/locales'; 13 13 import { openModal } from '~/globals/modals'; ··· 58 58 const moderationOptions = inject(ModerationService); 59 59 60 60 const author = () => post().author; 61 - const record = () => post().record as AppBskyFeedPost.Record; 61 + const record = () => post().record as AppBskyFeedPost.Main; 62 62 const embed = () => post().embed; 63 63 64 64 const shadow = usePostShadow(post); 65 65 66 - const uri = parseCanonicalResourceUri(post().uri); 66 + const { rkey } = assertCanonicalResourceUri(post().uri); 67 67 const authorDid = author().did; 68 68 69 69 const isOurPost = currentAccount && authorDid === currentAccount.did; 70 70 71 71 const authorHref = `/${authorDid}`; 72 - const href = `/${authorDid}/${uri.rkey}`; 72 + const href = `/${authorDid}/${rkey}`; 73 73 74 74 const moderation = createMemo(() => moderatePost(post(), moderationOptions())); 75 75 const ui = createMemo(() => getModerationUI(moderation(), ContextContentView)); ··· 151 151 } 152 152 153 153 if (props.translate) { 154 - return <PostTranslation text={(post().record as AppBskyFeedPost.Record).text} />; 154 + return <PostTranslation text={(post().record as AppBskyFeedPost.Main).text} />; 155 155 } 156 156 157 157 if (needTranslation(post(), currentAccount.preferences.translation)) { ··· 274 274 return false; 275 275 } 276 276 277 - const record = post.record as AppBskyFeedPost.Record; 277 + const record = post.record as AppBskyFeedPost.Main; 278 278 const langs = record.langs; 279 279 280 280 if (!langs || langs.length < 1 || !record.text) {
+2 -2
src/components/threads/overflow-thread-item.tsx
··· 1 1 import type { OverflowAncestorItem, OverflowDescendantItem } from '~/api/models/post-thread'; 2 - import { parseCanonicalResourceUri } from '~/api/types/at-uri'; 2 + import { assertCanonicalResourceUri } from '~/api/types/at-uri'; 3 3 4 4 import MoreHorizOutlinedIcon from '../icons-central/more-horiz-outline'; 5 5 ··· 20 20 return ( 21 21 <a 22 22 href={(() => { 23 - const uri = parseCanonicalResourceUri(props.item.uri); 23 + const uri = assertCanonicalResourceUri(props.item.uri); 24 24 return `/${uri.repo}/${uri.rkey}`; 25 25 })()} 26 26 class={
+4 -5
src/components/threads/post-thread-item.tsx
··· 1 1 import { type JSX, Show, createMemo } from 'solid-js'; 2 2 3 - import type { AppBskyFeedPost } from '@atcute/client/lexicons'; 3 + import type { AppBskyFeedPost } from '@atcute/bluesky'; 4 4 import { useQueryClient } from '@mary/solid-query'; 5 5 6 6 import { usePostShadow } from '~/api/cache/post-shadow'; ··· 9 9 import { ContextContentList } from '~/api/moderation/constants'; 10 10 import { moderatePost } from '~/api/moderation/entities/post'; 11 11 import { precacheProfile } from '~/api/queries-cache/profile-precache'; 12 - import { parseCanonicalResourceUri } from '~/api/types/at-uri'; 12 + import { assertCanonicalResourceUri } from '~/api/types/at-uri'; 13 13 14 14 import { history } from '~/globals/navigation'; 15 15 ··· 49 49 const post = () => item().post; 50 50 51 51 const author = () => post().author; 52 - const record = post().record as AppBskyFeedPost.Record; 52 + const record = post().record as AppBskyFeedPost.Main; 53 53 const embed = post().embed; 54 54 55 55 const shadow = usePostShadow(post); 56 56 57 - const uri = parseCanonicalResourceUri(post().uri); 58 57 const authorHref = `/${author().did}`; 59 - const href = `/${author().did}/${uri.rkey}`; 58 + const href = `/${author().did}/${assertCanonicalResourceUri(post().uri).rkey}`; 60 59 61 60 const isOurPost = currentAccount && currentAccount.did === author().did; 62 61
+7 -7
src/components/timeline/delete-post-prompt.tsx
··· 1 + import { AppBskyFeedDefs, AppBskyFeedPost } from '@atcute/bluesky'; 1 2 import { ClientResponseError, ok } from '@atcute/client'; 2 - import type { AppBskyFeedDefs, AppBskyFeedPost } from '@atcute/client/lexicons'; 3 3 import { useQueryClient } from '@mary/solid-query'; 4 4 5 5 import { updatePostShadow } from '~/api/cache/post-shadow'; 6 - import { parseCanonicalResourceUri } from '~/api/types/at-uri'; 6 + import { assertCanonicalResourceUri } from '~/api/types/at-uri'; 7 7 8 8 import { useAgent } from '~/lib/states/agent'; 9 9 import { useSession } from '~/lib/states/session'; ··· 24 24 const queryClient = useQueryClient(); 25 25 26 26 const onDelete = async () => { 27 - const uri = parseCanonicalResourceUri(post.uri); 27 + const { rkey } = assertCanonicalResourceUri(post.uri); 28 28 29 29 const write = await client.post('com.atproto.repo.applyWrites', { 30 30 input: { ··· 33 33 { 34 34 $type: 'com.atproto.repo.applyWrites#delete', 35 35 collection: 'app.bsky.feed.post', 36 - rkey: uri.rkey, 36 + rkey: rkey, 37 37 }, 38 38 ], 39 39 }, ··· 54 54 input: { 55 55 repo: currentAccount!.did, 56 56 collection: 'app.bsky.feed.post', 57 - rkey: uri.rkey, 57 + rkey: rkey, 58 58 validate: false, 59 59 record: { 60 60 $type: 'app.bsky.feed.post', 61 61 text: '', 62 62 createdAt: '1970-01-01T00:00:00.000Z', 63 - } satisfies AppBskyFeedPost.Record, 63 + } satisfies AppBskyFeedPost.Main, 64 64 }, 65 65 }), 66 66 ); ··· 70 70 input: { 71 71 repo: currentAccount!.did, 72 72 collection: 'app.bsky.feed.post', 73 - rkey: uri.rkey, 73 + rkey: rkey, 74 74 }, 75 75 }), 76 76 );
+1 -1
src/components/timeline/pin-post-prompt.tsx
··· 1 1 import { Match, Show, Switch, batch } from 'solid-js'; 2 2 3 + import type { AppBskyFeedDefs } from '@atcute/bluesky'; 3 4 import { ClientResponseError } from '@atcute/client'; 4 - import type { AppBskyFeedDefs } from '@atcute/client/lexicons'; 5 5 import { createMutation } from '@mary/solid-query'; 6 6 7 7 import { updatePostShadow, usePostShadow } from '~/api/cache/post-shadow';
+1 -1
src/components/timeline/post-actions.tsx
··· 1 - import type { AppBskyFeedDefs } from '@atcute/client/lexicons'; 1 + import type { AppBskyFeedDefs } from '@atcute/bluesky'; 2 2 3 3 import { type PostShadowView } from '~/api/cache/post-shadow'; 4 4 import { createPostLikeMutation, createPostRepostMutation } from '~/api/mutations/post';
+8 -6
src/components/timeline/post-feed-item.tsx
··· 1 1 import { createMemo } from 'solid-js'; 2 2 3 - import type { AppBskyFeedPost, At } from '@atcute/client/lexicons'; 3 + import type { AppBskyFeedPost } from '@atcute/bluesky'; 4 + import { type Did } from '@atcute/lexicons'; 4 5 import { useQueryClient } from '@mary/solid-query'; 5 6 6 7 import { usePostShadow } from '~/api/cache/post-shadow'; ··· 9 10 import { ContextContentList } from '~/api/moderation/constants'; 10 11 import { moderatePost } from '~/api/moderation/entities/post'; 11 12 import { precacheProfile } from '~/api/queries-cache/profile-precache'; 12 - import { parseCanonicalResourceUri } from '~/api/types/at-uri'; 13 + import { assertCanonicalResourceUri } from '~/api/types/at-uri'; 13 14 14 15 import { history } from '~/globals/navigation'; 15 16 ··· 36 37 /** Expected to be static */ 37 38 item: UiTimelineItem; 38 39 highlighted?: boolean; 39 - timelineDid?: At.Did; 40 + timelineDid?: Did; 40 41 } 41 42 42 43 const PostFeedItem = ({ item, highlighted, timelineDid }: PostFeedItemProps) => { ··· 50 51 const author = post.author; 51 52 const authorDid = author.did; 52 53 53 - const record = post.record as AppBskyFeedPost.Record; 54 + const record = post.record as AppBskyFeedPost.Main; 54 55 const embed = post.embed; 55 56 56 57 const shadow = usePostShadow(post); 57 58 58 - const uri = parseCanonicalResourceUri(post.uri); 59 + const { rkey } = assertCanonicalResourceUri(post.uri); 60 + 59 61 const authorHref = `/${authorDid}`; 60 - const href = `/${authorDid}/${uri.rkey}`; 62 + const href = `/${authorDid}/${rkey}`; 61 63 62 64 const isOurPost = currentAccount && authorDid === currentAccount.did; 63 65
+1 -1
src/components/timeline/post-meta.tsx
··· 1 - import type { AppBskyFeedDefs } from '@atcute/client/lexicons'; 1 + import type { AppBskyFeedDefs } from '@atcute/bluesky'; 2 2 import { useQueryClient } from '@mary/solid-query'; 3 3 4 4 import { precacheProfile } from '~/api/queries-cache/profile-precache';
+1 -1
src/components/timeline/post-overflow-menu.tsx
··· 1 1 import { createMemo } from 'solid-js'; 2 2 3 - import type { AppBskyFeedDefs } from '@atcute/client/lexicons'; 3 + import type { AppBskyFeedDefs } from '@atcute/bluesky'; 4 4 import { useQueryClient } from '@mary/solid-query'; 5 5 6 6 import { usePostShadow } from '~/api/cache/post-shadow';
+5 -4
src/components/timeline/post-reply-context.tsx
··· 1 - import type { AppBskyFeedPost } from '@atcute/client/lexicons'; 1 + import type { AppBskyFeedPost } from '@atcute/bluesky'; 2 2 3 3 import type { UiTimelineItem } from '~/api/models/timeline'; 4 4 import { createProfileQuery } from '~/api/queries/profile'; 5 - import { parseCanonicalResourceUri } from '~/api/types/at-uri'; 5 + import { assertCanonicalResourceUri } from '~/api/types/at-uri'; 6 6 7 7 import { useSession } from '~/lib/states/session'; 8 8 ··· 41 41 ); 42 42 } 43 43 44 - const raw = (post.record as AppBskyFeedPost.Record).reply?.parent; 44 + const raw = (post.record as AppBskyFeedPost.Main).reply?.parent; 45 45 if (raw) { 46 - const did = parseCanonicalResourceUri(raw.uri).repo; 46 + const { repo: did } = assertCanonicalResourceUri(raw.uri); 47 + 47 48 if (did === currentAccount?.did) { 48 49 return <div class="mb-0.5 flex text-de text-contrast-muted">Replying to you</div>; 49 50 }
+4 -4
src/components/timeline/post-share-menu.tsx
··· 1 - import type { AppBskyFeedDefs, AppBskyFeedPost } from '@atcute/client/lexicons'; 1 + import type { AppBskyFeedDefs, AppBskyFeedPost } from '@atcute/bluesky'; 2 2 3 - import { parseCanonicalResourceUri } from '~/api/types/at-uri'; 3 + import { assertCanonicalResourceUri } from '~/api/types/at-uri'; 4 4 import { serializeRichText } from '~/api/utils/richtext-stringify'; 5 5 6 6 import { useModalContext } from '~/globals/modals'; ··· 21 21 const post = props.post; 22 22 23 23 const did = post.author.did; 24 - const { rkey } = parseCanonicalResourceUri(post.uri); 24 + const { rkey } = assertCanonicalResourceUri(post.uri); 25 25 26 26 return ( 27 27 <Menu.Container anchor={props.anchor} placement="bottom-end"> ··· 38 38 icon={ClipboardOutlinedIcon} 39 39 label="Copy post text" 40 40 onClick={() => { 41 - const record = post.record as AppBskyFeedPost.Record; 41 + const record = post.record as AppBskyFeedPost.Main; 42 42 const serialized = serializeRichText(record.text, record.facets); 43 43 44 44 navigator.clipboard.writeText(serialized).then(close);
+37 -24
src/components/timeline/revise-post-prompt.tsx
··· 1 - import type { AppBskyFeedDefs, AppBskyFeedPost, AppBskyFeedThreadgate } from '@atcute/client/lexicons'; 1 + import { 2 + type AppBskyFeedDefs, 3 + type AppBskyFeedPost, 4 + type AppBskyFeedThreadgate, 5 + type RawMediaEmbed, 6 + type RawRecordEmbed, 7 + unwrapRawEmbed, 8 + } from '@atcute/bluesky'; 2 9 3 - import { parseCanonicalResourceUri } from '~/api/types/at-uri'; 4 - import { type MediaEmbed, type RecordEmbed, unwrapEmbed } from '~/api/utils/bluesky/embed'; 10 + import { assertCanonicalResourceUri } from '~/api/types/at-uri'; 5 11 import { serializeRichText } from '~/api/utils/richtext-stringify'; 6 12 7 13 import { openModal, useModalContext } from '~/globals/modals'; ··· 15 21 import { 16 22 type ComposerState, 17 23 type PostEmbed, 24 + type PostImage, 18 25 type PostLinkEmbed, 19 26 type PostMediaEmbed, 20 27 type PostRecordEmbed, ··· 32 39 const { close } = useModalContext(); 33 40 34 41 (async () => { 35 - const record = post.record as AppBskyFeedPost.Record; 36 - const threadgate = post.threadgate?.record as AppBskyFeedThreadgate.Record | undefined; 42 + const record = post.record as AppBskyFeedPost.Main; 43 + const threadgate = post.threadgate?.record as AppBskyFeedThreadgate.Main | undefined; 37 44 const embeddingDisabled = post.viewer?.embeddingDisabled; 38 45 39 - const embeds = unwrapEmbed(record.embed); 46 + const embeds = unwrapRawEmbed(record.embed); 40 47 const draftEmbeds: PostEmbed = { 41 48 link: embeds.media ? toLinkEmbed(post, embeds.media) : undefined, 42 49 media: embeds.media ? toMediaEmbed(post, embeds.media) : undefined, ··· 76 83 77 84 export default RevisePostPrompt; 78 85 79 - const toMediaEmbed = (post: AppBskyFeedDefs.PostView, embed: MediaEmbed): PostMediaEmbed | undefined => { 86 + const toMediaEmbed = (post: AppBskyFeedDefs.PostView, embed: RawMediaEmbed): PostMediaEmbed | undefined => { 80 87 const authorDid = post.author.did; 81 88 82 89 switch (embed.$type) { 83 90 case 'app.bsky.embed.images': { 84 91 return { 85 92 type: 'image', 86 - images: embed.images.map((item) => ({ 87 - source: { 88 - type: 'remote', 89 - blob: item.image, 90 - aspectRatio: item.aspectRatio, 91 - }, 92 - alt: item.alt, 93 - })), 93 + images: embed.images.map((item): PostImage => { 94 + assert('$type' in item.image); 95 + 96 + return { 97 + source: { 98 + type: 'remote', 99 + blob: item.image, 100 + aspectRatio: item.aspectRatio, 101 + }, 102 + alt: item.alt, 103 + }; 104 + }), 94 105 labels: post.labels?.filter((label) => label.src === authorDid).map((label) => label.val) ?? [], 95 106 }; 96 107 } 97 108 case 'app.bsky.embed.video': { 109 + assert('$type' in embed.video); 110 + 98 111 return { 99 112 type: 'video', 100 113 source: { ··· 109 122 } 110 123 }; 111 124 112 - const toLinkEmbed = (post: AppBskyFeedDefs.PostView, embed: MediaEmbed): PostLinkEmbed | undefined => { 125 + const toLinkEmbed = (post: AppBskyFeedDefs.PostView, embed: RawMediaEmbed): PostLinkEmbed | undefined => { 113 126 const authorDid = post.author.did; 114 127 115 128 switch (embed.$type) { ··· 129 142 } 130 143 }; 131 144 132 - const toRecordEmbed = (embed: RecordEmbed): PostRecordEmbed | undefined => { 145 + const toRecordEmbed = (embed: RawRecordEmbed): PostRecordEmbed | undefined => { 133 146 const ref = embed.record; 134 147 135 - const uri = ref.uri; 136 - const { collection } = parseCanonicalResourceUri(uri); 148 + const refUri = ref.uri; 149 + const uri = assertCanonicalResourceUri(refUri); 137 150 138 - switch (collection) { 151 + switch (uri.collection) { 139 152 case 'app.bsky.feed.post': { 140 - return { type: 'quote', uri, origin: false }; 153 + return { type: 'quote', uri: refUri, origin: false }; 141 154 } 142 155 case 'app.bsky.graph.list': { 143 - return { type: 'list', uri }; 156 + return { type: 'list', uri: refUri }; 144 157 } 145 158 case 'app.bsky.feed.generator': { 146 - return { type: 'feed', uri }; 159 + return { type: 'feed', uri: refUri }; 147 160 } 148 161 } 149 162 150 - assert(false, `unknown "${collection}" record type`); 163 + assert(false, `unknown "${uri.collection}" record type`); 151 164 };
+2 -2
src/components/timeline/timeline-list.tsx
··· 1 - import type { At } from '@atcute/client/lexicons'; 1 + import type { Did } from '@atcute/lexicons'; 2 2 3 3 import { type TimelineParams, useTimelineQuery } from '~/api/queries/timeline'; 4 4 ··· 9 9 10 10 export interface TimelineListProps { 11 11 params: TimelineParams; 12 - timelineDid?: At.Did; 12 + timelineDid?: Did; 13 13 } 14 14 15 15 const TimelineList = (props: TimelineListProps) => {
+1 -1
src/lib/aglais-bookmarks/db.ts
··· 1 1 import type { DBSchema } from 'idb'; 2 2 3 - import type { AppBskyFeedDefs } from '@atcute/client/lexicons'; 3 + import type { AppBskyFeedDefs } from '@atcute/bluesky'; 4 4 5 5 export interface BookmarkDBSchema extends DBSchema { 6 6 tags: {
+2 -2
src/lib/aglais-bookmarks/search.ts
··· 1 + import type { AppBskyFeedDefs, AppBskyFeedPost } from '@atcute/bluesky'; 1 2 import type { Token } from '@atcute/bluesky-search-parser'; 2 - import type { AppBskyFeedDefs, AppBskyFeedPost } from '@atcute/client/lexicons'; 3 3 import { mapDefined } from '@mary/array-fns'; 4 4 5 5 import { DID_RE, HANDLE_RE } from '~/api/types/identity'; ··· 84 84 }); 85 85 86 86 const re = new RegExp('\\b' + values.join('|') + '\\b', 'i'); 87 - predicates.push((post) => re.test((post.record as AppBskyFeedPost.Record).text)); 87 + predicates.push((post) => re.test((post.record as AppBskyFeedPost.Main).text)); 88 88 } 89 89 90 90 return (post: AppBskyFeedDefs.PostView) => predicates.every((fn) => fn(post));
+23 -3
src/lib/atproto/labeler.ts
··· 1 1 import { type FetchHandler, type FetchHandlerObject, buildFetchHandler } from '@atcute/client'; 2 - import type { At } from '@atcute/client/lexicons'; 3 - import { mergeHeaders } from '@atcute/client/utils/http'; 2 + import type { Did } from '@atcute/lexicons'; 4 3 5 4 export interface Labeler { 6 - did: At.Did; 5 + did: Did; 7 6 redact: boolean; 8 7 } 9 8 ··· 24 23 }); 25 24 }; 26 25 }; 26 + 27 + const mergeHeaders = ( 28 + init: HeadersInit | undefined, 29 + defaults: Record<string, string | null>, 30 + ): HeadersInit | undefined => { 31 + let headers: Headers | undefined; 32 + 33 + for (const name in defaults) { 34 + const value = defaults[name]; 35 + 36 + if (value !== null) { 37 + headers ??= new Headers(init); 38 + 39 + if (!headers.has(name)) { 40 + headers.set(name, value); 41 + } 42 + } 43 + } 44 + 45 + return headers ?? init; 46 + };
+1 -1
src/lib/bsky/image.ts
··· 1 - import type { AppBskyEmbedDefs } from '@atcute/client/lexicons'; 1 + import type { AppBskyEmbedDefs } from '@atcute/bluesky'; 2 2 import { remove as removeExif } from '@mary/exif-rm'; 3 3 4 4 const MAX_SIZE = 1_000_000; // 1 MB
+4 -3
src/lib/preferences/account.ts
··· 1 - import type { AppBskyFeedDefs, AppBskyGraphDefs, At } from '@atcute/client/lexicons'; 1 + import type { AppBskyFeedDefs, AppBskyGraphDefs } from '@atcute/bluesky'; 2 + import type { Did, ResourceUri } from '@atcute/lexicons'; 2 3 3 4 import type { ModerationLabeler, ModerationPreferences } from '~/api/moderation'; 4 5 ··· 28 29 29 30 export interface ModerationLabelerPreferences { 30 31 updated: number; 31 - definitions: Record<At.Did, ModerationLabeler>; 32 + definitions: Record<Did, ModerationLabeler>; 32 33 } 33 34 34 35 export type SavedFeed = SavedGeneratorFeed | SavedListFeed | SavedSearchFeed; ··· 54 55 55 56 export interface PersistedThreadgate { 56 57 allow?: Array< 57 - { type: 'following' } | { type: 'follower' } | { type: 'mention' } | { type: 'list'; uri: At.ResourceUri } 58 + { type: 'following' } | { type: 'follower' } | { type: 'mention' } | { type: 'list'; uri: ResourceUri } 58 59 >; 59 60 } 60 61
+4 -3
src/lib/preferences/sessions.ts
··· 1 - import type { AppBskyActorDefs, At } from '@atcute/client/lexicons'; 1 + import type { AppBskyActorDefs } from '@atcute/bluesky'; 2 + import type { Did } from '@atcute/lexicons'; 2 3 3 4 export interface SessionPreferenceSchema { 4 5 $version: 1; 5 - active: At.Did | undefined; 6 + active: Did | undefined; 6 7 accounts: AccountData[]; 7 8 } 8 9 9 10 export interface AccountData { 10 11 /** Account DID */ 11 - readonly did: At.Did; 12 + readonly did: Did; 12 13 profile: AppBskyActorDefs.ProfileViewDetailed; 13 14 }
+3 -3
src/lib/preferences/snippets/composer.ts
··· 1 - import type { AppBskyFeedPostgate, AppBskyFeedThreadgate } from '@atcute/client/lexicons'; 1 + import type { AppBskyFeedPostgate, AppBskyFeedThreadgate } from '@atcute/bluesky'; 2 2 3 3 import type { PersistedPostgate, PersistedThreadgate } from '../account'; 4 4 5 - export type ThreadgateState = Pick<AppBskyFeedThreadgate.Record, 'allow' | 'hiddenReplies'>; 6 - export type PostgateState = Pick<AppBskyFeedPostgate.Record, 'detachedEmbeddingUris' | 'embeddingRules'>; 5 + export type ThreadgateState = Pick<AppBskyFeedThreadgate.Main, 'allow' | 'hiddenReplies'>; 6 + export type PostgateState = Pick<AppBskyFeedPostgate.Main, 'detachedEmbeddingUris' | 'embeddingRules'>; 7 7 8 8 export const toPersistedThreadgate = (gate: ThreadgateState): PersistedThreadgate => { 9 9 return {
+2 -2
src/lib/states/agent.tsx
··· 1 1 import { type JSX, type ParentProps, createContext, createMemo, useContext } from 'solid-js'; 2 2 3 3 import { Client, simpleFetchHandler } from '@atcute/client'; 4 - import type { At } from '@atcute/client/lexicons'; 4 + import type { Did } from '@atcute/lexicons'; 5 5 import type { OAuthUserAgent } from '@atcute/oauth-browser-client'; 6 6 import { QueryClient, QueryClientProvider } from '@mary/solid-query'; 7 7 ··· 14 14 import { useSession } from './session'; 15 15 16 16 export interface AgentContext { 17 - did: At.Did | null; 17 + did: Did | null; 18 18 client: Client; 19 19 handler: OAuthUserAgent | null; 20 20 persister: ReturnType<typeof createQueryPersister>;
+10 -10
src/lib/states/session.tsx
··· 11 11 } from 'solid-js'; 12 12 13 13 import { Client, ClientResponseError, type FetchHandler, type FetchHandlerObject } from '@atcute/client'; 14 - import type { At } from '@atcute/client/lexicons'; 14 + import type { Did, GenericUri } from '@atcute/lexicons'; 15 15 import { OAuthUserAgent, deleteStoredSession, getSession } from '@atcute/oauth-browser-client'; 16 16 import { mapDefined } from '@mary/array-fns'; 17 17 ··· 27 27 import { assert } from '../utils/invariant'; 28 28 29 29 export interface CurrentAccountState { 30 - readonly did: At.Did; 30 + readonly did: Did; 31 31 readonly data: AccountData; 32 32 readonly preferences: PerAccountPreferenceSchema; 33 33 ··· 40 40 readonly currentAccount: CurrentAccountState | undefined; 41 41 42 42 getAccounts(): AccountData[]; 43 - resumeSession(did: At.Did): Promise<void>; 44 - removeAccount(did: At.Did): Promise<void>; 43 + resumeSession(did: Did): Promise<void>; 44 + removeAccount(did: Did): Promise<void>; 45 45 46 46 logout(): Promise<void>; 47 47 } ··· 60 60 }; 61 61 62 62 const createAccountState = ( 63 - did: At.Did, 63 + did: Did, 64 64 session: OAuthUserAgent | undefined, 65 65 client: Client, 66 66 ): CurrentAccountState => { ··· 75 75 76 76 const labelers = createMemo((): Labeler[] => { 77 77 return Object.entries(preferences.moderation.labelers).map(([did, info]): Labeler => { 78 - return { did: did as At.Did, redact: info.redact }; 78 + return { did: did as Did, redact: info.redact }; 79 79 }); 80 80 }); 81 81 ··· 144 144 getAccounts(): AccountData[] { 145 145 return sessions.accounts; 146 146 }, 147 - async resumeSession(did: At.Did): Promise<void> { 147 + async resumeSession(did: Did): Promise<void> { 148 148 const account = sessions.accounts.find((acc) => acc.did === did); 149 149 if (!account) { 150 150 return; ··· 197 197 }); 198 198 }, 199 199 200 - async removeAccount(did: At.Did): Promise<void> { 200 + async removeAccount(did: Did): Promise<void> { 201 201 const $state = untrack(state); 202 202 const isLoggedIn = $state !== undefined && $state.did === did; 203 203 ··· 246 246 return session; 247 247 }; 248 248 249 - const createAccountPreferences = (did: At.Did) => { 249 + const createAccountPreferences = (did: Did) => { 250 250 const key = `account-${did}`; 251 251 return createReactiveLocalStorage<PerAccountPreferenceSchema>(key, (version, prev) => { 252 252 if (version === 0) { ··· 282 282 }, 283 283 displayName: 'Popular With Friends', 284 284 description: '', 285 - avatar: '' as At.GenericUri, 285 + avatar: '' as GenericUri, 286 286 indexedAt: '0000-00-00T00:00:00.000Z', 287 287 }, 288 288 },
+4 -4
src/lib/states/singletons/moderation.ts
··· 2 2 import { unwrap } from 'solid-js/store'; 3 3 4 4 import { ok } from '@atcute/client'; 5 - import type { At } from '@atcute/client/lexicons'; 5 + import type { Did } from '@atcute/lexicons'; 6 6 import { mapDefined } from '@mary/array-fns'; 7 7 import { createBatchedFetch } from '@mary/batch-fetch'; 8 8 import { type QueryFunctionContext as QC, createQueries } from '@mary/solid-query'; ··· 38 38 return currentAccount.preferences.moderation; 39 39 }); 40 40 41 - const fetchLabeler = createBatchedFetch<At.Did, ModerationLabeler>({ 41 + const fetchLabeler = createBatchedFetch<Did, ModerationLabeler>({ 42 42 limit: 20, 43 43 timeout: 1, 44 44 idFromResource: (labeler) => labeler.did, ··· 61 61 const labelerDefs = createQueries(() => { 62 62 return { 63 63 queries: Object.keys(modPreferences().labelers).map((_did) => { 64 - const did = _did as At.Did; 64 + const did = _did as Did; 65 65 66 66 return { 67 67 queryKey: ['labeler-definition', did], ··· 76 76 const defs = mapDefined(results, (result) => result.data); 77 77 const fields = Object.fromEntries(defs.map((def) => [def.did, def])); 78 78 79 - return fields as Record<At.Did, ModerationLabeler>; 79 + return fields as Record<Did, ModerationLabeler>; 80 80 }, 81 81 }; 82 82 });
+2 -2
src/main.tsx
··· 2 2 import { type JSX, createSignal, onMount } from 'solid-js'; 3 3 import { render } from 'solid-js/web'; 4 4 5 - import type { At } from '@atcute/client/lexicons'; 5 + import type { Did } from '@atcute/lexicons'; 6 6 import { configureOAuth } from '@atcute/oauth-browser-client'; 7 7 8 8 import * as navigation from '~/globals/navigation'; ··· 44 44 const session = useSession(); 45 45 46 46 onMount(() => { 47 - const resumeAccount = async (did: At.Did | undefined) => { 47 + const resumeAccount = async (did: Did | undefined) => { 48 48 try { 49 49 if (did) { 50 50 await session.resumeSession(did);
+2 -2
src/shell.tsx
··· 8 8 lazy, 9 9 } from 'solid-js'; 10 10 11 - import type { AppBskyNotificationGetUnreadCount } from '@atcute/client/lexicons'; 11 + import type { AppBskyNotificationGetUnreadCount } from '@atcute/bluesky'; 12 12 import type { DefinedCreateQueryResult } from '@mary/solid-query'; 13 13 14 14 import { createNotificationCountQuery } from '~/api/queries/notification-count'; ··· 99 99 unread, 100 100 }: { 101 101 route: Accessor<MatchedRouteState>; 102 - unread: DefinedCreateQueryResult<AppBskyNotificationGetUnreadCount.Output>; 102 + unread: DefinedCreateQueryResult<AppBskyNotificationGetUnreadCount.$output>; 103 103 }) => { 104 104 const active = () => route().def.meta?.name; 105 105
+2 -1
src/views/bluemoji-emotes.tsx
··· 1 1 import { type JSX, createEffect, createSignal } from 'solid-js'; 2 2 3 + import type { Blob as AtpBlob } from '@atcute/lexicons'; 3 4 import { remove as removeExif } from '@mary/exif-rm'; 4 5 import { createInfiniteQuery } from '@mary/solid-query'; 5 6 ··· 113 114 return ( 114 115 <div class="flex items-center gap-4 px-4 py-4"> 115 116 <img 116 - src={/* @once */ getCdnUrl(currentAccount!.did, blob!.ref.$link)} 117 + src={/* @once */ getCdnUrl(currentAccount!.did, (blob! as AtpBlob).ref.$link)} 117 118 class="h-8 w-8 object-cover" 118 119 /> 119 120
+3 -3
src/views/post-likes.tsx
··· 1 - import type { At } from '@atcute/client/lexicons'; 1 + import type { Did, RecordKey } from '@atcute/lexicons'; 2 2 3 3 import { createSubjectLikersQuery } from '~/api/queries/subject-likers'; 4 4 import { makeAtUri } from '~/api/types/at-uri'; ··· 13 13 14 14 const PostLikesPage = () => { 15 15 const { did, rkey } = useParams<{ 16 - did: At.Did; 17 - rkey: At.RecordKey; 16 + did: Did; 17 + rkey: RecordKey; 18 18 }>(); 19 19 20 20 const uri = makeAtUri(did, 'app.bsky.feed.post', rkey);
+3 -3
src/views/post-quotes.tsx
··· 1 - import type { At } from '@atcute/client/lexicons'; 1 + import type { Did, RecordKey } from '@atcute/lexicons'; 2 2 3 3 import { createPostQuotesQuery } from '~/api/queries/post-quotes'; 4 4 import { makeAtUri } from '~/api/types/at-uri'; ··· 12 12 13 13 const PostQuotesPage = () => { 14 14 const { did, rkey } = useParams<{ 15 - did: At.Did; 16 - rkey: At.RecordKey; 15 + did: Did; 16 + rkey: RecordKey; 17 17 }>(); 18 18 19 19 const uri = makeAtUri(did, 'app.bsky.feed.post', rkey);
+3 -3
src/views/post-reposts.tsx
··· 1 - import type { At } from '@atcute/client/lexicons'; 1 + import type { Did, RecordKey } from '@atcute/lexicons'; 2 2 3 3 import { createSubjectRepostersQuery } from '~/api/queries/subject-reposters'; 4 4 import { makeAtUri } from '~/api/types/at-uri'; ··· 13 13 14 14 const PostLikesPage = () => { 15 15 const { did, rkey } = useParams<{ 16 - did: At.Did; 17 - rkey: At.RecordKey; 16 + did: Did; 17 + rkey: RecordKey; 18 18 }>(); 19 19 20 20 const uri = makeAtUri(did, 'app.bsky.feed.post', rkey);
+8 -7
src/views/post-thread.tsx
··· 1 1 import { For, Match, Switch, createEffect, createMemo, createSignal } from 'solid-js'; 2 2 3 + import type { AppBskyFeedDefs, AppBskyFeedPost } from '@atcute/bluesky'; 3 4 import { ClientResponseError } from '@atcute/client'; 4 - import type { AppBskyFeedDefs, AppBskyFeedPost, At, Brand } from '@atcute/client/lexicons'; 5 + import type { $type, ActorIdentifier, Did, RecordKey } from '@atcute/lexicons'; 5 6 import { useQueryClient } from '@mary/solid-query'; 6 7 7 8 import { ··· 39 40 40 41 const PostThreadPage = () => { 41 42 const { didOrHandle, rkey } = useParams<{ 42 - didOrHandle: At.Identifier; 43 - rkey: At.RecordKey; 43 + didOrHandle: ActorIdentifier; 44 + rkey: RecordKey; 44 45 }>(); 45 46 46 47 const queryClient = useQueryClient(); ··· 53 54 if (data && data.$type === 'app.bsky.feed.defs#threadViewPost') { 54 55 const post = data.post; 55 56 const author = post.author; 56 - const record = post.record as AppBskyFeedPost.Record; 57 + const record = post.record as AppBskyFeedPost.Main; 57 58 58 59 const authorTitle = `@${truncateMiddle(author.handle, 29).toLowerCase()}`; 59 60 const postContent = record.text?.trim(); ··· 105 106 const data = accessor(); 106 107 const type = data.$type; 107 108 108 - let did: At.Did | undefined; 109 + let did: Did | undefined; 109 110 110 111 if (type === 'app.bsky.feed.defs#threadViewPost') { 111 112 did = data.post.author.did; ··· 220 221 export default PostThreadPage; 221 222 222 223 const ThreadView = (props: { 223 - data: Brand.Union<AppBskyFeedDefs.ThreadViewPost>; 224 + data: $type.enforce<AppBskyFeedDefs.ThreadViewPost>; 224 225 isPlaceholderData: boolean; 225 226 onReplyPublish?: () => void; 226 227 onMainPostDelete?: () => void; ··· 260 261 } 261 262 } 262 263 263 - return (post.record as AppBskyFeedPost.Record).reply !== undefined; 264 + return (post.record as AppBskyFeedPost.Main).reply !== undefined; 264 265 }; 265 266 266 267 return (
+3 -3
src/views/profile-curation-list.tsx
··· 1 1 import { Match, Switch } from 'solid-js'; 2 2 3 - import type { At } from '@atcute/client/lexicons'; 3 + import type { Did, RecordKey } from '@atcute/lexicons'; 4 4 5 5 import { createListMetaQuery } from '~/api/queries/list'; 6 6 import { makeAtUri } from '~/api/types/at-uri'; ··· 14 14 15 15 const CurationListPage = () => { 16 16 const { did, rkey } = useParams<{ 17 - did: At.Did; 18 - rkey: At.RecordKey; 17 + did: Did; 18 + rkey: RecordKey; 19 19 }>(); 20 20 21 21 const uri = makeAtUri(did, 'app.bsky.graph.list', rkey);
+3 -3
src/views/profile-feed.tsx
··· 1 1 import { Match, Show, Switch } from 'solid-js'; 2 2 3 - import type { At } from '@atcute/client/lexicons'; 3 + import type { ActorIdentifier, RecordKey } from '@atcute/lexicons'; 4 4 import { useQueryClient } from '@mary/solid-query'; 5 5 6 6 import { createFeedMetaQuery } from '~/api/queries/feed'; ··· 25 25 26 26 const FeedPage = () => { 27 27 const { didOrHandle, rkey } = useParams<{ 28 - didOrHandle: At.Identifier; 29 - rkey: At.RecordKey; 28 + didOrHandle: ActorIdentifier; 29 + rkey: RecordKey; 30 30 }>(); 31 31 32 32 const queryClient = useQueryClient();
+2 -4
src/views/profile-feeds.tsx
··· 1 - import type { At } from '@atcute/client/lexicons'; 1 + import type { Did } from '@atcute/lexicons'; 2 2 3 3 import { createProfileQuery } from '~/api/queries/profile'; 4 4 import { createProfileFeedsQuery } from '~/api/queries/profile-feeds'; ··· 11 11 import VirtualItem from '~/components/virtual-item'; 12 12 13 13 const ProfileFeedsPage = () => { 14 - const { did } = useParams<{ 15 - did: At.Did; 16 - }>(); 14 + const { did } = useParams<{ did: Did }>(); 17 15 18 16 const feeds = createProfileFeedsQuery(() => did); 19 17 const profile = createProfileQuery(() => did);
+2 -4
src/views/profile-followers.tsx
··· 1 1 import { createMemo } from 'solid-js'; 2 2 3 - import type { At } from '@atcute/client/lexicons'; 3 + import type { Did } from '@atcute/lexicons'; 4 4 5 5 import { createProfileFollowersQuery } from '~/api/queries/profile-followers'; 6 6 ··· 13 13 import VirtualItem from '~/components/virtual-item'; 14 14 15 15 const ProfileFollowersPage = () => { 16 - const { did } = useParams<{ 17 - did: At.Did; 18 - }>(); 16 + const { did } = useParams<{ did: Did }>(); 19 17 20 18 const followers = createProfileFollowersQuery(() => did); 21 19 const subject = createMemo(() => followers.data?.pages[0].subject);
+2 -4
src/views/profile-following.tsx
··· 1 1 import { createMemo } from 'solid-js'; 2 2 3 - import type { At } from '@atcute/client/lexicons'; 3 + import type { Did } from '@atcute/lexicons'; 4 4 5 5 import { createProfileFollowingQuery } from '~/api/queries/profile-following'; 6 6 ··· 13 13 import VirtualItem from '~/components/virtual-item'; 14 14 15 15 const ProfileFollowingPage = () => { 16 - const { did } = useParams<{ 17 - did: At.Did; 18 - }>(); 16 + const { did } = useParams<{ did: Did }>(); 19 17 20 18 const following = createProfileFollowingQuery(() => did); 21 19 const subject = createMemo(() => following.data?.pages[0].subject);
+2 -4
src/views/profile-known-followers.tsx
··· 1 1 import { createMemo } from 'solid-js'; 2 2 3 - import type { At } from '@atcute/client/lexicons'; 3 + import type { Did } from '@atcute/lexicons'; 4 4 5 5 import { createProfileKnownFollowersQuery } from '~/api/queries/profile-known-followers'; 6 6 ··· 13 13 import VirtualItem from '~/components/virtual-item'; 14 14 15 15 const ProfileKnownFollowersPage = () => { 16 - const { did } = useParams<{ 17 - did: At.Did; 18 - }>(); 16 + const { did } = useParams<{ did: Did }>(); 19 17 20 18 const followers = createProfileKnownFollowersQuery(() => did); 21 19 const subject = createMemo(() => followers.data?.pages[0].subject);
+6 -6
src/views/profile-labels.tsx
··· 1 1 import { Match, Show, Switch, createMemo } from 'solid-js'; 2 2 3 - import type { At } from '@atcute/client/lexicons'; 3 + import type { Did } from '@atcute/lexicons'; 4 4 import { mapDefined } from '@mary/array-fns'; 5 5 6 6 import { ··· 46 46 import LabelerOverflowMenu from '~/components/settings/moderation/labeling/labeler-overflow-menu'; 47 47 48 48 const ProfileLabelsPage = () => { 49 - const { did } = useParams(); 49 + const { did } = useParams<{ did: Did }>(); 50 50 const { currentAccount } = useSession(); 51 51 52 - const query = createLabelerMetaQuery(() => did as At.Did); 52 + const query = createLabelerMetaQuery(() => did); 53 53 54 54 const config = createMemo(() => { 55 55 if (!currentAccount) { ··· 57 57 } 58 58 59 59 const preferences = currentAccount.preferences; 60 - return preferences.moderation.labelers[did as At.Did]; 60 + return preferences.moderation.labelers[did]; 61 61 }); 62 62 63 63 useTitle(() => { ··· 98 98 const preferences = currentAccount!.preferences; 99 99 const labelers = preferences.moderation.labelers; 100 100 101 - labelers[did as At.Did] = { 101 + labelers[did] = { 102 102 labels: {}, 103 103 privileged: false, 104 104 redact: false, ··· 140 140 const preferences = currentAccount!.preferences; 141 141 const labelers = preferences.moderation.labelers; 142 142 143 - delete labelers[did as At.Did]; 143 + delete labelers[did]; 144 144 }} 145 145 /> 146 146 ));
+3 -3
src/views/profile-list.tsx
··· 1 1 import { Match, Switch } from 'solid-js'; 2 2 3 - import type { At } from '@atcute/client/lexicons'; 3 + import type { ActorIdentifier, RecordKey } from '@atcute/lexicons'; 4 4 import { useQueryClient } from '@mary/solid-query'; 5 5 6 6 import { createListMetaQuery } from '~/api/queries/list'; ··· 17 17 18 18 const ListStubPage = () => { 19 19 const { didOrHandle, rkey } = useParams<{ 20 - didOrHandle: At.Identifier; 21 - rkey: At.RecordKey; 20 + didOrHandle: ActorIdentifier; 21 + rkey: RecordKey; 22 22 }>(); 23 23 24 24 const queryClient = useQueryClient();
+2 -4
src/views/profile-lists.tsx
··· 1 - import type { At } from '@atcute/client/lexicons'; 1 + import type { Did } from '@atcute/lexicons'; 2 2 3 3 import { createProfileQuery } from '~/api/queries/profile'; 4 4 import { createProfileListsQuery } from '~/api/queries/profile-lists'; ··· 10 10 import PagedList from '~/components/paged-list'; 11 11 12 12 const ProfileListsPage = () => { 13 - const { did } = useParams<{ 14 - did: At.Did; 15 - }>(); 13 + const { did } = useParams<{ did: Did }>(); 16 14 17 15 const lists = createProfileListsQuery(() => did); 18 16 const profile = createProfileQuery(() => did);
+5 -4
src/views/profile-moderation-list.tsx
··· 1 1 import { Match, Show, Switch, createMemo } from 'solid-js'; 2 2 3 - import type { AppBskyGraphDefs, At } from '@atcute/client/lexicons'; 3 + import type { AppBskyGraphDefs } from '@atcute/bluesky'; 4 + import type { Did, RecordKey, ResourceUri } from '@atcute/lexicons'; 4 5 import { useQueryClient } from '@mary/solid-query'; 5 6 6 7 import { ContextContentMedia } from '~/api/moderation/constants'; ··· 30 31 31 32 const ProfileModerationListPage = () => { 32 33 const { did, rkey } = useParams<{ 33 - did: At.Did; 34 - rkey: At.RecordKey; 34 + did: Did; 35 + rkey: RecordKey; 35 36 }>(); 36 37 37 38 const uri = makeAtUri(did, 'app.bsky.graph.list', rkey); ··· 163 164 ); 164 165 }; 165 166 166 - const MembersList = ({ uri }: { uri: At.ResourceUri }) => { 167 + const MembersList = ({ uri }: { uri: ResourceUri }) => { 167 168 const members = createListMembersQuery(() => uri); 168 169 169 170 return (
+2 -2
src/views/profile-search.tsx
··· 1 1 import { createSignal } from 'solid-js'; 2 2 3 - import type { At } from '@atcute/client/lexicons'; 3 + import type { ActorIdentifier } from '@atcute/lexicons'; 4 4 5 5 import { createProfileQuery } from '~/api/queries/profile'; 6 6 import { isDid } from '~/api/types/identity'; ··· 17 17 18 18 const ProfileSearchPage = () => { 19 19 const { didOrHandle } = useParams<{ 20 - didOrHandle: At.Identifier; 20 + didOrHandle: ActorIdentifier; 21 21 }>(); 22 22 23 23 const [query, setQuery] = createSignal('');
+3 -2
src/views/profile.tsx
··· 1 1 import { Match, Show, Switch, createMemo } from 'solid-js'; 2 2 3 + import type { AppBskyActorDefs } from '@atcute/bluesky'; 3 4 import { ClientResponseError } from '@atcute/client'; 4 - import type { AppBskyActorDefs, At } from '@atcute/client/lexicons'; 5 + import type { ActorIdentifier } from '@atcute/lexicons'; 5 6 import { useQueryClient } from '@mary/solid-query'; 6 7 7 8 import { useProfileShadow } from '~/api/cache/profile-shadow'; ··· 32 33 33 34 const ProfilePage = () => { 34 35 const { didOrHandle } = useParams<{ 35 - didOrHandle: At.Identifier; 36 + didOrHandle: ActorIdentifier; 36 37 }>(); 37 38 38 39 const queryClient = useQueryClient();
+1 -1
src/views/settings-app-passwords.tsx
··· 1 1 import { For, Match, Show, Switch } from 'solid-js'; 2 2 3 + import type { ComAtprotoServerListAppPasswords } from '@atcute/atproto'; 3 4 import { ok } from '@atcute/client'; 4 - import type { ComAtprotoServerListAppPasswords } from '@atcute/client/lexicons'; 5 5 import { createMutation, createQuery } from '@mary/solid-query'; 6 6 7 7 import { openModal } from '~/globals/modals';
+8 -1
tsconfig.json
··· 2 2 "compilerOptions": { 3 3 "target": "ESNext", 4 4 "lib": ["DOM", "DOM.Iterable", "ESNext"], 5 - "types": ["dom-close-watcher", "dom-webcodecs"], 5 + "types": [ 6 + "dom-close-watcher", 7 + "dom-webcodecs", 8 + "@atcute/atproto", 9 + "@atcute/bluemoji", 10 + "@atcute/bluesky", 11 + "@kelinci/basa-lexicons", 12 + ], 6 13 "skipLibCheck": true, 7 14 8 15 "module": "ESNext",