tangled
alpha
login
or
join now
flo-bit.dev
/
blento
your personal website on atproto - mirror
blento.app
20
fork
atom
overview
issues
pulls
pipelines
add some caching
Florian
1 month ago
d7578d0d
96324db6
+181
-40
11 changed files
expand all
collapse all
unified
split
package.json
pnpm-lock.yaml
src
app.d.ts
lib
helper.ts
website
load.ts
routes
+page.server.ts
+page.svelte
[handle]
+layout.server.ts
+page.svelte
api
refreshData
+server.ts
wrangler.jsonc
+2
-1
package.json
···
43
"dependencies": {
44
"@atcute/client": "^3.1.0",
45
"@atcute/oauth-browser-client": "^1.0.13",
46
-
"@atproto/api": "^0.15.6",
47
"@atproto/common-web": "^0.4.2",
0
48
"@foxui/colors": "^0.4.7",
49
"@foxui/core": "^0.4.7",
50
"@foxui/social": "^0.4.7",
···
43
"dependencies": {
44
"@atcute/client": "^3.1.0",
45
"@atcute/oauth-browser-client": "^1.0.13",
46
+
"@atproto/api": "^0.18.13",
47
"@atproto/common-web": "^0.4.2",
48
+
"@cloudflare/workers-types": "^4.20260109.0",
49
"@foxui/colors": "^0.4.7",
50
"@foxui/core": "^0.4.7",
51
"@foxui/social": "^0.4.7",
+91
-25
pnpm-lock.yaml
···
15
specifier: ^1.0.13
16
version: 1.0.18
17
'@atproto/api':
18
-
specifier: ^0.15.6
19
-
version: 0.15.6
20
'@atproto/common-web':
21
specifier: ^0.4.2
22
version: 0.4.2
0
0
0
23
'@foxui/colors':
24
specifier: ^0.4.7
25
version: 0.4.7(svelte@5.45.8)(tailwindcss@4.1.5)
···
97
version: 7.2.0
98
wrangler:
99
specifier: ^4.54.0
100
-
version: 4.54.0(@cloudflare/workers-types@4.20251225.0)
101
devDependencies:
102
'@eslint/compat':
103
specifier: ^1.2.5
···
110
version: 4.0.0(@sveltejs/kit@2.20.8(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.45.8)(vite@6.3.5(jiti@2.4.2)(lightningcss@1.29.2)))(svelte@5.45.8)(vite@6.3.5(jiti@2.4.2)(lightningcss@1.29.2)))
111
'@sveltejs/adapter-cloudflare':
112
specifier: ^7.2.4
113
-
version: 7.2.4(@sveltejs/kit@2.20.8(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.45.8)(vite@6.3.5(jiti@2.4.2)(lightningcss@1.29.2)))(svelte@5.45.8)(vite@6.3.5(jiti@2.4.2)(lightningcss@1.29.2)))(wrangler@4.54.0(@cloudflare/workers-types@4.20251225.0))
114
'@sveltejs/adapter-static':
115
specifier: ^3.0.8
116
version: 3.0.8(@sveltejs/kit@2.20.8(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.45.8)(vite@6.3.5(jiti@2.4.2)(lightningcss@1.29.2)))(svelte@5.45.8)(vite@6.3.5(jiti@2.4.2)(lightningcss@1.29.2)))
···
183
'@atcute/uint8array@1.0.1':
184
resolution: {integrity: sha512-AAnlFKyfDRgb9GNZJbhQ6OuMhbmNPirQyapb8KnmcEhxQZ3+tt+4NcwqekEegY4MpNqSTYeeTdyxq0wGZv1JHg==, tarball: https://registry.npmjs.org/@atcute/uint8array/-/uint8array-1.0.1.tgz}
185
186
-
'@atproto/api@0.15.6':
187
-
resolution: {integrity: sha512-hKwrBf60LcI4BqArWyrhWJWIpjwAWUJpW3PVvNzUB1q2W/ByC0JAuwq/F8tZpCEiiVBzHjHVRx4QNA2TA1cG3g==, tarball: https://registry.npmjs.org/@atproto/api/-/api-0.15.6.tgz}
0
0
0
0
0
0
188
189
'@atproto/common-web@0.4.2':
190
resolution: {integrity: sha512-vrXwGNoFGogodjQvJDxAeP3QbGtawgZute2ed1XdRO0wMixLk3qewtikZm06H259QDJVu6voKC5mubml+WgQUw==, tarball: https://registry.npmjs.org/@atproto/common-web/-/common-web-0.4.2.tgz}
191
192
-
'@atproto/lexicon@0.4.11':
193
-
resolution: {integrity: sha512-btefdnvNz2Ao2I+qbmj0F06HC8IlrM/IBz6qOBS50r0S6uDf5tOO+Mv2tSVdimFkdzyDdLtBI1sV36ONxz2cOw==, tarball: https://registry.npmjs.org/@atproto/lexicon/-/lexicon-0.4.11.tgz}
0
0
0
0
0
0
0
0
0
194
195
'@atproto/syntax@0.4.0':
196
resolution: {integrity: sha512-b9y5ceHS8YKOfP3mdKmwAx5yVj9294UN7FG2XzP6V5aKUdFazEYRnR9m5n5ZQFKa3GNvz7de9guZCJ/sUTcOAA==, tarball: https://registry.npmjs.org/@atproto/syntax/-/syntax-0.4.0.tgz}
197
198
-
'@atproto/xrpc@0.7.0':
199
-
resolution: {integrity: sha512-SfhP9dGx2qclaScFDb58Jnrmim5nk4geZXCqg6sB0I/KZhZEkr9iIx1hLCp+sxkIfEsmEJjeWO4B0rjUIJW5cw==, tarball: https://registry.npmjs.org/@atproto/xrpc/-/xrpc-0.7.0.tgz}
0
0
0
200
201
'@cloudflare/kv-asset-handler@0.4.1':
202
resolution: {integrity: sha512-Nu8ahitGFFJztxUml9oD/DLb7Z28C8cd8F46IVQ7y5Btz575pvMY8AqZsXkX7Gds29eCKdMgIHjIvzskHgPSFg==, tarball: https://registry.npmjs.org/@cloudflare/kv-asset-handler/-/kv-asset-handler-0.4.1.tgz}
···
241
cpu: [x64]
242
os: [win32]
243
244
-
'@cloudflare/workers-types@4.20251225.0':
245
-
resolution: {integrity: sha512-ZZl0cNLFcsBRFKtMftKWOsfAybUYSeiTMzpQV1NlTVlByHAs1rGQt45Jw/qz8LrfHoq9PGTieSj9W350Gi4Pvg==, tarball: https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20251225.0.tgz}
246
247
'@cspotcode/source-map-support@0.8.1':
248
resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==, tarball: https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz}
···
2663
unenv@2.0.0-rc.24:
2664
resolution: {integrity: sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw==, tarball: https://registry.npmjs.org/unenv/-/unenv-2.0.0-rc.24.tgz}
2665
0
0
0
2666
unpipe@1.0.0:
2667
resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==, tarball: https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz}
2668
engines: {node: '>= 0.8'}
···
2818
2819
'@atcute/uint8array@1.0.1': {}
2820
2821
-
'@atproto/api@0.15.6':
2822
dependencies:
2823
'@atproto/common-web': 0.4.2
2824
-
'@atproto/lexicon': 0.4.11
2825
'@atproto/syntax': 0.4.0
2826
-
'@atproto/xrpc': 0.7.0
2827
await-lock: 2.2.2
2828
multiformats: 9.9.0
2829
tlds: 1.258.0
2830
zod: 3.24.4
2831
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
2832
'@atproto/common-web@0.4.2':
2833
dependencies:
2834
graphemer: 1.4.0
···
2836
uint8arrays: 3.0.0
2837
zod: 3.24.4
2838
2839
-
'@atproto/lexicon@0.4.11':
0
0
0
0
0
0
0
0
0
0
0
0
0
2840
dependencies:
2841
'@atproto/common-web': 0.4.2
2842
'@atproto/syntax': 0.4.0
···
2844
multiformats: 9.9.0
2845
zod: 3.24.4
2846
0
0
0
0
0
0
0
0
2847
'@atproto/syntax@0.4.0': {}
2848
2849
-
'@atproto/xrpc@0.7.0':
0
0
2850
dependencies:
2851
-
'@atproto/lexicon': 0.4.11
2852
zod: 3.24.4
2853
2854
'@cloudflare/kv-asset-handler@0.4.1':
···
2876
'@cloudflare/workerd-windows-64@1.20251210.0':
2877
optional: true
2878
2879
-
'@cloudflare/workers-types@4.20251225.0': {}
2880
2881
'@cspotcode/source-map-support@0.8.1':
2882
dependencies:
···
3122
3123
'@foxui/social@0.4.7(svelte@5.45.8)(tailwindcss@4.1.5)':
3124
dependencies:
3125
-
'@atproto/api': 0.15.6
3126
'@foxui/core': 0.4.7(svelte@5.45.8)(tailwindcss@4.1.5)
3127
'@foxui/time': 0.4.7(svelte@5.45.8)(tailwindcss@4.1.5)
3128
'@use-gesture/vanilla': 10.3.1
···
3387
'@sveltejs/kit': 2.20.8(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.45.8)(vite@6.3.5(jiti@2.4.2)(lightningcss@1.29.2)))(svelte@5.45.8)(vite@6.3.5(jiti@2.4.2)(lightningcss@1.29.2))
3388
import-meta-resolve: 4.1.0
3389
3390
-
'@sveltejs/adapter-cloudflare@7.2.4(@sveltejs/kit@2.20.8(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.45.8)(vite@6.3.5(jiti@2.4.2)(lightningcss@1.29.2)))(svelte@5.45.8)(vite@6.3.5(jiti@2.4.2)(lightningcss@1.29.2)))(wrangler@4.54.0(@cloudflare/workers-types@4.20251225.0))':
3391
dependencies:
3392
-
'@cloudflare/workers-types': 4.20251225.0
3393
'@sveltejs/kit': 2.20.8(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.45.8)(vite@6.3.5(jiti@2.4.2)(lightningcss@1.29.2)))(svelte@5.45.8)(vite@6.3.5(jiti@2.4.2)(lightningcss@1.29.2))
3394
worktop: 0.8.0-next.18
3395
-
wrangler: 4.54.0(@cloudflare/workers-types@4.20251225.0)
3396
3397
'@sveltejs/adapter-static@3.0.8(@sveltejs/kit@2.20.8(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.45.8)(vite@6.3.5(jiti@2.4.2)(lightningcss@1.29.2)))(svelte@5.45.8)(vite@6.3.5(jiti@2.4.2)(lightningcss@1.29.2)))':
3398
dependencies:
···
5213
dependencies:
5214
pathe: 2.0.3
5215
0
0
5216
unpipe@1.0.0: {}
5217
5218
uri-js@4.4.1:
···
5263
mrmime: 2.0.1
5264
regexparam: 3.0.0
5265
5266
-
wrangler@4.54.0(@cloudflare/workers-types@4.20251225.0):
5267
dependencies:
5268
'@cloudflare/kv-asset-handler': 0.4.1
5269
'@cloudflare/unenv-preset': 2.7.13(unenv@2.0.0-rc.24)(workerd@1.20251210.0)
···
5274
unenv: 2.0.0-rc.24
5275
workerd: 1.20251210.0
5276
optionalDependencies:
5277
-
'@cloudflare/workers-types': 4.20251225.0
5278
fsevents: 2.3.3
5279
transitivePeerDependencies:
5280
- bufferutil
···
15
specifier: ^1.0.13
16
version: 1.0.18
17
'@atproto/api':
18
+
specifier: ^0.18.13
19
+
version: 0.18.13
20
'@atproto/common-web':
21
specifier: ^0.4.2
22
version: 0.4.2
23
+
'@cloudflare/workers-types':
24
+
specifier: ^4.20260109.0
25
+
version: 4.20260109.0
26
'@foxui/colors':
27
specifier: ^0.4.7
28
version: 0.4.7(svelte@5.45.8)(tailwindcss@4.1.5)
···
100
version: 7.2.0
101
wrangler:
102
specifier: ^4.54.0
103
+
version: 4.54.0(@cloudflare/workers-types@4.20260109.0)
104
devDependencies:
105
'@eslint/compat':
106
specifier: ^1.2.5
···
113
version: 4.0.0(@sveltejs/kit@2.20.8(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.45.8)(vite@6.3.5(jiti@2.4.2)(lightningcss@1.29.2)))(svelte@5.45.8)(vite@6.3.5(jiti@2.4.2)(lightningcss@1.29.2)))
114
'@sveltejs/adapter-cloudflare':
115
specifier: ^7.2.4
116
+
version: 7.2.4(@sveltejs/kit@2.20.8(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.45.8)(vite@6.3.5(jiti@2.4.2)(lightningcss@1.29.2)))(svelte@5.45.8)(vite@6.3.5(jiti@2.4.2)(lightningcss@1.29.2)))(wrangler@4.54.0(@cloudflare/workers-types@4.20260109.0))
117
'@sveltejs/adapter-static':
118
specifier: ^3.0.8
119
version: 3.0.8(@sveltejs/kit@2.20.8(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.45.8)(vite@6.3.5(jiti@2.4.2)(lightningcss@1.29.2)))(svelte@5.45.8)(vite@6.3.5(jiti@2.4.2)(lightningcss@1.29.2)))
···
186
'@atcute/uint8array@1.0.1':
187
resolution: {integrity: sha512-AAnlFKyfDRgb9GNZJbhQ6OuMhbmNPirQyapb8KnmcEhxQZ3+tt+4NcwqekEegY4MpNqSTYeeTdyxq0wGZv1JHg==, tarball: https://registry.npmjs.org/@atcute/uint8array/-/uint8array-1.0.1.tgz}
188
189
+
'@atproto/api@0.15.27':
190
+
resolution: {integrity: sha512-ok/WGafh1nz4t8pEQGtAF/32x2E2VDWU4af6BajkO5Gky2jp2q6cv6aB2A5yuvNNcc3XkYMYipsqVHVwLPMF9g==, tarball: https://registry.npmjs.org/@atproto/api/-/api-0.15.27.tgz}
191
+
192
+
'@atproto/api@0.18.13':
193
+
resolution: {integrity: sha512-CULZ01pSJDltLS/Gc9MMrhFzB6OM3ezyZw7KoeLT/sBfwgA1ddA4mWdTh7DIRosPRigXtA05bnoiCutZbQDo+Q==, tarball: https://registry.npmjs.org/@atproto/api/-/api-0.18.13.tgz}
194
+
195
+
'@atproto/common-web@0.4.11':
196
+
resolution: {integrity: sha512-VHejNmSABU8/03VrQ3e36AmT5U3UIeio+qSUqCrO1oNgrJcWfGy1rpj0FVtUugWF8Un29+yzkukzWGZfXL70rQ==, tarball: https://registry.npmjs.org/@atproto/common-web/-/common-web-0.4.11.tgz}
197
198
'@atproto/common-web@0.4.2':
199
resolution: {integrity: sha512-vrXwGNoFGogodjQvJDxAeP3QbGtawgZute2ed1XdRO0wMixLk3qewtikZm06H259QDJVu6voKC5mubml+WgQUw==, tarball: https://registry.npmjs.org/@atproto/common-web/-/common-web-0.4.2.tgz}
200
201
+
'@atproto/lex-data@0.0.7':
202
+
resolution: {integrity: sha512-W/Q5o9o7n2Sv3UywckChu01X5lwQUtaiiOkGJLnRsdkQTyC6813nPgY+p2sG7NwwM+82lu+FUV9fE/Ul3VqaJw==, tarball: https://registry.npmjs.org/@atproto/lex-data/-/lex-data-0.0.7.tgz}
203
+
204
+
'@atproto/lex-json@0.0.7':
205
+
resolution: {integrity: sha512-bjNPD5M/MhLfjNM7tcxuls80UgXpHqxdOxDXEUouAtZQV/nIDhGjmNUvKxOmOgnDsiZRnT2g5y3onrnjH3a44g==, tarball: https://registry.npmjs.org/@atproto/lex-json/-/lex-json-0.0.7.tgz}
206
+
207
+
'@atproto/lexicon@0.4.14':
208
+
resolution: {integrity: sha512-jiKpmH1QER3Gvc7JVY5brwrfo+etFoe57tKPQX/SmPwjvUsFnJAow5xLIryuBaJgFAhnTZViXKs41t//pahGHQ==, tarball: https://registry.npmjs.org/@atproto/lexicon/-/lexicon-0.4.14.tgz}
209
+
210
+
'@atproto/lexicon@0.6.0':
211
+
resolution: {integrity: sha512-5veb8aD+J5M0qszLJ+73KSFsFrJBgAY/nM1TSAJvGY7fNc9ZAT+PSUlmIyrdye9YznAZ07yktalls/TwNV7cHQ==, tarball: https://registry.npmjs.org/@atproto/lexicon/-/lexicon-0.6.0.tgz}
212
213
'@atproto/syntax@0.4.0':
214
resolution: {integrity: sha512-b9y5ceHS8YKOfP3mdKmwAx5yVj9294UN7FG2XzP6V5aKUdFazEYRnR9m5n5ZQFKa3GNvz7de9guZCJ/sUTcOAA==, tarball: https://registry.npmjs.org/@atproto/syntax/-/syntax-0.4.0.tgz}
215
216
+
'@atproto/syntax@0.4.2':
217
+
resolution: {integrity: sha512-X9XSRPinBy/0VQ677j8VXlBsYSsUXaiqxWVpGGxJYsAhugdQRb0jqaVKJFtm6RskeNkV6y9xclSUi9UYG/COrA==, tarball: https://registry.npmjs.org/@atproto/syntax/-/syntax-0.4.2.tgz}
218
+
219
+
'@atproto/xrpc@0.7.7':
220
+
resolution: {integrity: sha512-K1ZyO/BU8JNtXX5dmPp7b5UrkLMMqpsIa/Lrj5D3Su+j1Xwq1m6QJ2XJ1AgjEjkI1v4Muzm7klianLE6XGxtmA==, tarball: https://registry.npmjs.org/@atproto/xrpc/-/xrpc-0.7.7.tgz}
221
222
'@cloudflare/kv-asset-handler@0.4.1':
223
resolution: {integrity: sha512-Nu8ahitGFFJztxUml9oD/DLb7Z28C8cd8F46IVQ7y5Btz575pvMY8AqZsXkX7Gds29eCKdMgIHjIvzskHgPSFg==, tarball: https://registry.npmjs.org/@cloudflare/kv-asset-handler/-/kv-asset-handler-0.4.1.tgz}
···
262
cpu: [x64]
263
os: [win32]
264
265
+
'@cloudflare/workers-types@4.20260109.0':
266
+
resolution: {integrity: sha512-90vx2lVm+fhQyE8FKqNhT8JBI8GuY0biAwxTzvzeRIdWVo2ArCpUfYMYq4kzaGTfA6NwCmXmBFSgnqfG6OFxLw==, tarball: https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20260109.0.tgz}
267
268
'@cspotcode/source-map-support@0.8.1':
269
resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==, tarball: https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz}
···
2684
unenv@2.0.0-rc.24:
2685
resolution: {integrity: sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw==, tarball: https://registry.npmjs.org/unenv/-/unenv-2.0.0-rc.24.tgz}
2686
2687
+
unicode-segmenter@0.14.5:
2688
+
resolution: {integrity: sha512-jHGmj2LUuqDcX3hqY12Ql+uhUTn8huuxNZGq7GvtF6bSybzH3aFgedYu/KTzQStEgt1Ra2F3HxadNXsNjb3m3g==, tarball: https://registry.npmjs.org/unicode-segmenter/-/unicode-segmenter-0.14.5.tgz}
2689
+
2690
unpipe@1.0.0:
2691
resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==, tarball: https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz}
2692
engines: {node: '>= 0.8'}
···
2842
2843
'@atcute/uint8array@1.0.1': {}
2844
2845
+
'@atproto/api@0.15.27':
2846
dependencies:
2847
'@atproto/common-web': 0.4.2
2848
+
'@atproto/lexicon': 0.4.14
2849
'@atproto/syntax': 0.4.0
2850
+
'@atproto/xrpc': 0.7.7
2851
await-lock: 2.2.2
2852
multiformats: 9.9.0
2853
tlds: 1.258.0
2854
zod: 3.24.4
2855
2856
+
'@atproto/api@0.18.13':
2857
+
dependencies:
2858
+
'@atproto/common-web': 0.4.11
2859
+
'@atproto/lexicon': 0.6.0
2860
+
'@atproto/syntax': 0.4.2
2861
+
'@atproto/xrpc': 0.7.7
2862
+
await-lock: 2.2.2
2863
+
multiformats: 9.9.0
2864
+
tlds: 1.258.0
2865
+
zod: 3.24.4
2866
+
2867
+
'@atproto/common-web@0.4.11':
2868
+
dependencies:
2869
+
'@atproto/lex-data': 0.0.7
2870
+
'@atproto/lex-json': 0.0.7
2871
+
zod: 3.24.4
2872
+
2873
'@atproto/common-web@0.4.2':
2874
dependencies:
2875
graphemer: 1.4.0
···
2877
uint8arrays: 3.0.0
2878
zod: 3.24.4
2879
2880
+
'@atproto/lex-data@0.0.7':
2881
+
dependencies:
2882
+
'@atproto/syntax': 0.4.2
2883
+
multiformats: 9.9.0
2884
+
tslib: 2.8.1
2885
+
uint8arrays: 3.0.0
2886
+
unicode-segmenter: 0.14.5
2887
+
2888
+
'@atproto/lex-json@0.0.7':
2889
+
dependencies:
2890
+
'@atproto/lex-data': 0.0.7
2891
+
tslib: 2.8.1
2892
+
2893
+
'@atproto/lexicon@0.4.14':
2894
dependencies:
2895
'@atproto/common-web': 0.4.2
2896
'@atproto/syntax': 0.4.0
···
2898
multiformats: 9.9.0
2899
zod: 3.24.4
2900
2901
+
'@atproto/lexicon@0.6.0':
2902
+
dependencies:
2903
+
'@atproto/common-web': 0.4.11
2904
+
'@atproto/syntax': 0.4.2
2905
+
iso-datestring-validator: 2.2.2
2906
+
multiformats: 9.9.0
2907
+
zod: 3.24.4
2908
+
2909
'@atproto/syntax@0.4.0': {}
2910
2911
+
'@atproto/syntax@0.4.2': {}
2912
+
2913
+
'@atproto/xrpc@0.7.7':
2914
dependencies:
2915
+
'@atproto/lexicon': 0.6.0
2916
zod: 3.24.4
2917
2918
'@cloudflare/kv-asset-handler@0.4.1':
···
2940
'@cloudflare/workerd-windows-64@1.20251210.0':
2941
optional: true
2942
2943
+
'@cloudflare/workers-types@4.20260109.0': {}
2944
2945
'@cspotcode/source-map-support@0.8.1':
2946
dependencies:
···
3186
3187
'@foxui/social@0.4.7(svelte@5.45.8)(tailwindcss@4.1.5)':
3188
dependencies:
3189
+
'@atproto/api': 0.15.27
3190
'@foxui/core': 0.4.7(svelte@5.45.8)(tailwindcss@4.1.5)
3191
'@foxui/time': 0.4.7(svelte@5.45.8)(tailwindcss@4.1.5)
3192
'@use-gesture/vanilla': 10.3.1
···
3451
'@sveltejs/kit': 2.20.8(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.45.8)(vite@6.3.5(jiti@2.4.2)(lightningcss@1.29.2)))(svelte@5.45.8)(vite@6.3.5(jiti@2.4.2)(lightningcss@1.29.2))
3452
import-meta-resolve: 4.1.0
3453
3454
+
'@sveltejs/adapter-cloudflare@7.2.4(@sveltejs/kit@2.20.8(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.45.8)(vite@6.3.5(jiti@2.4.2)(lightningcss@1.29.2)))(svelte@5.45.8)(vite@6.3.5(jiti@2.4.2)(lightningcss@1.29.2)))(wrangler@4.54.0(@cloudflare/workers-types@4.20260109.0))':
3455
dependencies:
3456
+
'@cloudflare/workers-types': 4.20260109.0
3457
'@sveltejs/kit': 2.20.8(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.45.8)(vite@6.3.5(jiti@2.4.2)(lightningcss@1.29.2)))(svelte@5.45.8)(vite@6.3.5(jiti@2.4.2)(lightningcss@1.29.2))
3458
worktop: 0.8.0-next.18
3459
+
wrangler: 4.54.0(@cloudflare/workers-types@4.20260109.0)
3460
3461
'@sveltejs/adapter-static@3.0.8(@sveltejs/kit@2.20.8(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.45.8)(vite@6.3.5(jiti@2.4.2)(lightningcss@1.29.2)))(svelte@5.45.8)(vite@6.3.5(jiti@2.4.2)(lightningcss@1.29.2)))':
3462
dependencies:
···
5277
dependencies:
5278
pathe: 2.0.3
5279
5280
+
unicode-segmenter@0.14.5: {}
5281
+
5282
unpipe@1.0.0: {}
5283
5284
uri-js@4.4.1:
···
5329
mrmime: 2.0.1
5330
regexparam: 3.0.0
5331
5332
+
wrangler@4.54.0(@cloudflare/workers-types@4.20260109.0):
5333
dependencies:
5334
'@cloudflare/kv-asset-handler': 0.4.1
5335
'@cloudflare/unenv-preset': 2.7.13(unenv@2.0.0-rc.24)(workerd@1.20251210.0)
···
5340
unenv: 2.0.0-rc.24
5341
workerd: 1.20251210.0
5342
optionalDependencies:
5343
+
'@cloudflare/workers-types': 4.20260109.0
5344
fsevents: 2.3.3
5345
transitivePeerDependencies:
5346
- bufferutil
+7
-1
src/app.d.ts
···
0
0
1
// See https://svelte.dev/docs/kit/types#app.d.ts
2
// for information about these interfaces
3
declare global {
···
6
// interface Locals {}
7
// interface PageData {}
8
// interface PageState {}
9
-
// interface Platform {}
0
0
0
0
10
}
11
}
12
···
1
+
import { KVNamespace } from '@cloudflare/workers-types';
2
+
3
// See https://svelte.dev/docs/kit/types#app.d.ts
4
// for information about these interfaces
5
declare global {
···
8
// interface Locals {}
9
// interface PageData {}
10
// interface PageState {}
11
+
interface Platform {
12
+
env: {
13
+
USER_DATA_CACHE: KVNamespace;
14
+
};
15
+
}
16
}
17
}
18
+16
src/lib/helper.ts
···
150
151
export const [getAdditionalUserData, setAdditionalUserData] =
152
createContext<Record<string, unknown>>();
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
···
150
151
export const [getAdditionalUserData, setAdditionalUserData] =
152
createContext<Record<string, unknown>>();
153
+
154
+
export async function refreshData(data: { updatedAt?: number; handle: string }) {
155
+
const FIVE_MINUTES = 5 * 60 * 1000;
156
+
const now = Date.now();
157
+
158
+
if (now - (data.updatedAt || 0) > FIVE_MINUTES) {
159
+
try {
160
+
await fetch('/' + data.handle + '/api/refreshData');
161
+
console.log('successfully refreshed data', data.handle);
162
+
} catch (error) {
163
+
console.error('error refreshing data', error);
164
+
}
165
+
} else {
166
+
console.log('data still fresh, skipping refreshing', data.handle);
167
+
}
168
+
}
+26
-5
src/lib/website/load.ts
···
7
import { getRecord, listRecords, resolveHandle } from '$lib/oauth/atproto';
8
import type { Record as ListRecord } from '@atproto/api/dist/client/types/com/atproto/repo/listRecords';
9
import { data } from './data';
10
-
import { AtpBaseClient } from '@atproto/api';
11
-
import { env } from '$env/dynamic/private';
12
import { CardDefinitionsByType } from '$lib/cards';
13
import type { Item } from '$lib/types';
14
15
-
export async function loadData(handle: string) {
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
16
const did = await resolveHandle({ handle });
17
18
const downloadedData = {} as DownloadedData;
···
97
}
98
}
99
100
-
return {
101
did,
102
data: JSON.parse(JSON.stringify(downloadedData)) as DownloadedData,
103
-
additionalData
0
104
};
0
0
0
0
105
}
···
7
import { getRecord, listRecords, resolveHandle } from '$lib/oauth/atproto';
8
import type { Record as ListRecord } from '@atproto/api/dist/client/types/com/atproto/repo/listRecords';
9
import { data } from './data';
0
0
10
import { CardDefinitionsByType } from '$lib/cards';
11
import type { Item } from '$lib/types';
12
13
+
export async function loadData(
14
+
handle: string,
15
+
platform?: App.Platform,
16
+
forceUpdate: boolean = false
17
+
): Promise<{
18
+
did: string;
19
+
data: DownloadedData;
20
+
additionalData: Record<string, unknown>;
21
+
updatedAt: number;
22
+
}> {
23
+
if (!forceUpdate) {
24
+
const cachedResult = await platform?.env?.USER_DATA_CACHE?.get(handle);
25
+
26
+
if (cachedResult) {
27
+
console.log('using cached result for handle', handle);
28
+
return JSON.parse(cachedResult);
29
+
}
30
+
}
31
+
32
const did = await resolveHandle({ handle });
33
34
const downloadedData = {} as DownloadedData;
···
113
}
114
}
115
116
+
const result = {
117
did,
118
data: JSON.parse(JSON.stringify(downloadedData)) as DownloadedData,
119
+
additionalData,
120
+
updatedAt: Date.now()
121
};
122
+
123
+
await platform?.env?.USER_DATA_CACHE?.put(handle, JSON.stringify(result));
124
+
125
+
return result;
126
}
+2
-2
src/routes/+page.server.ts
···
1
import { loadData } from '$lib/website/load';
2
import { env } from '$env/dynamic/public';
3
4
-
export async function load() {
5
-
const data = await loadData(env.PUBLIC_HANDLE);
6
return { ...data, handle: env.PUBLIC_HANDLE };
7
}
···
1
import { loadData } from '$lib/website/load';
2
import { env } from '$env/dynamic/public';
3
4
+
export async function load({ platform }) {
5
+
const data = await loadData(env.PUBLIC_HANDLE, platform);
6
return { ...data, handle: env.PUBLIC_HANDLE };
7
}
+6
-1
src/routes/+page.svelte
···
1
<script lang="ts">
2
-
import { setAdditionalUserData } from '$lib/helper.js';
3
import { type Item } from '$lib/types.js';
4
import Website from '$lib/Website.svelte';
0
5
6
let { data } = $props();
7
8
// svelte-ignore state_referenced_locally
9
setAdditionalUserData(data.additionalData);
0
0
0
0
10
</script>
11
12
<Website
···
1
<script lang="ts">
2
+
import { refreshData, setAdditionalUserData } from '$lib/helper.js';
3
import { type Item } from '$lib/types.js';
4
import Website from '$lib/Website.svelte';
5
+
import { onMount } from 'svelte';
6
7
let { data } = $props();
8
9
// svelte-ignore state_referenced_locally
10
setAdditionalUserData(data.additionalData);
11
+
12
+
onMount(() => {
13
+
refreshData(data);
14
+
});
15
</script>
16
17
<Website
+3
-2
src/routes/[handle]/+layout.server.ts
···
2
import { env } from '$env/dynamic/private';
3
import { error } from '@sveltejs/kit';
4
5
-
export async function load({ params }) {
6
if (env.PUBLIC_IS_SELFHOSTED) error(404);
7
-
return await loadData(params.handle);
0
8
}
···
2
import { env } from '$env/dynamic/private';
3
import { error } from '@sveltejs/kit';
4
5
+
export async function load({ params, platform }) {
6
if (env.PUBLIC_IS_SELFHOSTED) error(404);
7
+
const data = await loadData(params.handle, platform);
8
+
return { ...data, handle: params.handle };
9
}
+6
-1
src/routes/[handle]/+page.svelte
···
1
<script lang="ts">
2
import { page } from '$app/state';
3
-
import { setAdditionalUserData } from '$lib/helper.js';
4
import { type Item } from '$lib/types.js';
5
import Website from '$lib/Website.svelte';
0
6
7
let { data } = $props();
8
9
// svelte-ignore state_referenced_locally
10
setAdditionalUserData(data.additionalData);
0
0
0
0
11
</script>
12
13
<Website
···
1
<script lang="ts">
2
import { page } from '$app/state';
3
+
import { refreshData, setAdditionalUserData } from '$lib/helper.js';
4
import { type Item } from '$lib/types.js';
5
import Website from '$lib/Website.svelte';
6
+
import { onMount } from 'svelte';
7
8
let { data } = $props();
9
10
// svelte-ignore state_referenced_locally
11
setAdditionalUserData(data.additionalData);
12
+
13
+
onMount(() => {
14
+
refreshData(data);
15
+
})
16
</script>
17
18
<Website
+11
src/routes/[handle]/api/refreshData/+server.ts
···
0
0
0
0
0
0
0
0
0
0
0
···
1
+
import { loadData } from '$lib/website/load.js';
2
+
import { json } from '@sveltejs/kit';
3
+
4
+
export async function GET({ params, platform }) {
5
+
if (!platform?.env?.USER_DATA_CACHE) return json('no cache');
6
+
const handle = params.handle;
7
+
8
+
await loadData(handle, platform, true);
9
+
10
+
return json('ok');
11
+
}
+11
-2
wrangler.jsonc
···
7
"name": "blento",
8
"main": ".svelte-kit/cloudflare/_worker.js",
9
"compatibility_date": "2025-12-25",
10
-
"compatibility_flags": ["nodejs_als"],
0
0
11
"assets": {
12
"binding": "ASSETS",
13
"directory": ".svelte-kit/cloudflare"
···
36
"PUBLIC_HANDLE": "blento.app",
37
"PUBLIC_IS_SELFHOSTED": "",
38
"PUBLIC_DOMAIN": "https://blento.app"
39
-
}
0
0
0
0
0
0
0
40
/**
41
* Service Bindings (communicate between multiple Workers)
42
* https://developers.cloudflare.com/workers/wrangler/configuration/#service-bindings
···
7
"name": "blento",
8
"main": ".svelte-kit/cloudflare/_worker.js",
9
"compatibility_date": "2025-12-25",
10
+
"compatibility_flags": [
11
+
"nodejs_als"
12
+
],
13
"assets": {
14
"binding": "ASSETS",
15
"directory": ".svelte-kit/cloudflare"
···
38
"PUBLIC_HANDLE": "blento.app",
39
"PUBLIC_IS_SELFHOSTED": "",
40
"PUBLIC_DOMAIN": "https://blento.app"
41
+
},
42
+
"kv_namespaces": [
43
+
{
44
+
"binding": "USER_DATA_CACHE",
45
+
"id": "d6ff203259de48538d332b0a5df258a7",
46
+
"remote": true
47
+
}
48
+
]
49
/**
50
* Service Bindings (communicate between multiple Workers)
51
* https://developers.cloudflare.com/workers/wrangler/configuration/#service-bindings