+7
-4
package.json
+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
+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
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
+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
+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
-1
src/api/models/timeline.ts
+3
-2
src/api/moderation/entities/generic.ts
+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
+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
-1
src/api/moderation/entities/profile.ts
+2
-2
src/api/moderation/entities/quote.ts
+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
+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
-1
src/api/moderation/labeler.ts
+4
-4
src/api/mutations/post.ts
+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
+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
+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
-1
src/api/queries-cache/feed-precache.ts
+1
-1
src/api/queries-cache/list-precache.ts
+1
-1
src/api/queries-cache/list-precache.ts
+3
-2
src/api/queries-cache/notification-feed.ts
+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
+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
+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
+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
+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
-1
src/api/queries-cache/profile-precache.ts
+3
-2
src/api/queries-cache/profile.ts
+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
+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
+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
-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
+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
+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
+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
+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
+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
+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
-1
src/api/queries/my-lists.ts
+3
-3
src/api/queries/notification-feed.tsx
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
-1
src/api/types/profile-response.ts
-56
src/api/utils/bluesky/embed-view.ts
-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
-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
+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
+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
+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
-1
src/api/utils/richtext-stringify.ts
-17
src/atcute-env.d.ts
-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
-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
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
src/components/bookmarks/add-post-to-folder-dialog.tsx
+5
-4
src/components/bookmarks/bookmark-feed-item.tsx
+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
+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
+1
-1
src/components/composer/composer-input.tsx
+3
-4
src/components/composer/composer-reply-context.tsx
+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
+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
};
+5
-4
src/components/composer/embeds/link-embed.tsx
+5
-4
src/components/composer/embeds/link-embed.tsx
···
1
1
import { Match, Switch, onCleanup } from 'solid-js';
2
2
3
-
import type { AppBskyEmbedExternal, At } from '@atcute/client/lexicons';
3
+
import type { AppBskyEmbedExternal } from '@atcute/bluesky';
4
+
import type { GenericUri } from '@atcute/lexicons';
4
5
5
6
import { createLinkMetaQuery } from '~/api/queries/composer';
6
7
···
38
39
{(state) => {
39
40
const meta = state.external;
40
41
41
-
let thumbUrl: At.GenericUri | undefined;
42
-
if (meta.thumb) {
42
+
let thumbUrl: GenericUri | undefined;
43
+
if (meta.thumb && '$type' in meta.thumb) {
43
44
const did = currentAccount!.did;
44
45
const cid = meta.thumb.ref.$link;
45
46
···
85
86
title: data.title,
86
87
description: data.description,
87
88
uri: data.uri,
88
-
thumb: thumbUrl as At.GenericUri,
89
+
thumb: thumbUrl as GenericUri,
89
90
},
90
91
};
91
92
+1
-1
src/components/composer/embeds/quote-embed.tsx
+1
-1
src/components/composer/embeds/quote-embed.tsx
+3
-3
src/components/composer/gifs/gif-search-dialog.tsx
+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
+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
-4
src/components/composer/lib/link-detection.ts
+4
-4
src/components/composer/lib/link-detection.ts
···
1
-
import type { At } from '@atcute/client/lexicons';
1
+
import type { ActorIdentifier } from '@atcute/lexicons';
2
2
3
3
import { makeAtUri } from '~/api/types/at-uri';
4
4
import { safeUrlParse } from '~/api/utils/strings';
···
17
17
18
18
if (host === 'bsky.app') {
19
19
if ((match = BSKY_POST_LINK_RE.exec(path))) {
20
-
const didOrHandle = match[1] as At.Identifier;
20
+
const didOrHandle = match[1] as ActorIdentifier;
21
21
const rkey = match[2];
22
22
23
23
return {
···
28
28
}
29
29
30
30
if ((match = BSKY_FEED_LINK_RE.exec(path))) {
31
-
const didOrHandle = match[1] as At.Identifier;
31
+
const didOrHandle = match[1] as ActorIdentifier;
32
32
const rkey = match[2];
33
33
34
34
return {
···
38
38
}
39
39
40
40
if ((match = BSKY_LIST_LINK_RE.exec(path))) {
41
-
const didOrHandle = match[1] as At.Identifier;
41
+
const didOrHandle = match[1] as ActorIdentifier;
42
42
const rkey = match[2];
43
43
44
44
return {
+4
-9
src/components/composer/lib/state.tsx
+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
+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
src/components/embeds/external-embed.tsx
+3
-3
src/components/embeds/feed-embed.tsx
+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
-1
src/components/embeds/image-grid-embed.tsx
+1
-1
src/components/embeds/image-standalone-embed.tsx
+1
-1
src/components/embeds/image-standalone-embed.tsx
+1
-1
src/components/embeds/lib/image-utils.ts
+1
-1
src/components/embeds/lib/image-utils.ts
+1
-1
src/components/embeds/lib/snippet.tsx
+1
-1
src/components/embeds/lib/snippet.tsx
+1
-1
src/components/embeds/list-embed.tsx
+1
-1
src/components/embeds/list-embed.tsx
+1
-1
src/components/embeds/players/video-player.tsx
+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
+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
+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
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
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
+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
+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
+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
+3
-3
src/components/lists/lib/utils.ts
+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
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
+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
+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
src/components/moderation/labels-on-me.tsx
+1
-1
src/components/moderation/mute-account-prompt.tsx
+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
+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
+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/profile-item-pressable.tsx
+1
-1
src/components/profiles/profile-item-pressable.tsx
+1
-1
src/components/profiles/profile-item.tsx
+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';
+4
-4
src/components/profiles/profile-view-header.tsx
+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
+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
+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
+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
+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
+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
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
-1
src/components/timeline/post-actions.tsx
+8
-6
src/components/timeline/post-feed-item.tsx
+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
-1
src/components/timeline/post-meta.tsx
+5
-4
src/components/timeline/post-reply-context.tsx
+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
}
+37
-24
src/components/timeline/revise-post-prompt.tsx
+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
+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
src/lib/aglais-bookmarks/db.ts
+2
-2
src/lib/aglais-bookmarks/search.ts
+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
+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
-1
src/lib/bsky/image.ts
+4
-3
src/lib/preferences/account.ts
+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
+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
+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
+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
+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
+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
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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
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
+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",