diff --git a/deno.lock b/deno.lock index 834ec36..bdfba9b 100644 --- a/deno.lock +++ b/deno.lock @@ -1,156 +1,199 @@ { "version": "5", "specifiers": { + "npm:@atcute/atproto@^3.1.7": "3.1.7", + "npm:@atcute/bluesky@^3.2.7": "3.2.7", + "npm:@atcute/client@^4.0.5": "4.0.5", + "npm:@atcute/identity@^1.1.1": "1.1.1", + "npm:@atcute/lexicons@^1.2.2": "1.2.2", "npm:@eslint/compat@^1.4.0": "1.4.0_eslint@9.37.0", "npm:@eslint/js@^9.36.0": "9.37.0", - "npm:@sveltejs/adapter-auto@^6.1.0": "6.1.1_@sveltejs+kit@2.46.4__@sveltejs+vite-plugin-svelte@6.2.1___svelte@5.39.11____acorn@8.15.0___vite@7.1.9____@types+node@24.7.1____picomatch@4.0.3___@types+node@24.7.1__svelte@5.39.11___acorn@8.15.0__vite@7.1.9___@types+node@24.7.1___picomatch@4.0.3__acorn@8.15.0__@types+node@24.7.1_@sveltejs+vite-plugin-svelte@6.2.1__svelte@5.39.11___acorn@8.15.0__vite@7.1.9___@types+node@24.7.1___picomatch@4.0.3__@types+node@24.7.1_svelte@5.39.11__acorn@8.15.0_vite@7.1.9__@types+node@24.7.1__picomatch@4.0.3_@types+node@24.7.1", - "npm:@sveltejs/kit@^2.43.2": "2.46.4_@sveltejs+vite-plugin-svelte@6.2.1__svelte@5.39.11___acorn@8.15.0__vite@7.1.9___@types+node@24.7.1___picomatch@4.0.3__@types+node@24.7.1_svelte@5.39.11__acorn@8.15.0_vite@7.1.9__@types+node@24.7.1__picomatch@4.0.3_acorn@8.15.0_@types+node@24.7.1", - "npm:@sveltejs/vite-plugin-svelte@^6.2.0": "6.2.1_svelte@5.39.11__acorn@8.15.0_vite@7.1.9__@types+node@24.7.1__picomatch@4.0.3_@types+node@24.7.1", + "npm:@sveltejs/adapter-auto@^6.1.0": "6.1.1_@sveltejs+kit@2.47.0__@sveltejs+vite-plugin-svelte@6.2.1___svelte@5.40.1____acorn@8.15.0___vite@7.1.10____@types+node@24.8.0____picomatch@4.0.3___@types+node@24.8.0__svelte@5.40.1___acorn@8.15.0__vite@7.1.10___@types+node@24.8.0___picomatch@4.0.3__acorn@8.15.0__@types+node@24.8.0_@sveltejs+vite-plugin-svelte@6.2.1__svelte@5.40.1___acorn@8.15.0__vite@7.1.10___@types+node@24.8.0___picomatch@4.0.3__@types+node@24.8.0_svelte@5.40.1__acorn@8.15.0_vite@7.1.10__@types+node@24.8.0__picomatch@4.0.3_@types+node@24.8.0", + "npm:@sveltejs/kit@^2.43.2": "2.47.0_@sveltejs+vite-plugin-svelte@6.2.1__svelte@5.40.1___acorn@8.15.0__vite@7.1.10___@types+node@24.8.0___picomatch@4.0.3__@types+node@24.8.0_svelte@5.40.1__acorn@8.15.0_vite@7.1.10__@types+node@24.8.0__picomatch@4.0.3_acorn@8.15.0_@types+node@24.8.0", + "npm:@sveltejs/vite-plugin-svelte@^6.2.0": "6.2.1_svelte@5.40.1__acorn@8.15.0_vite@7.1.10__@types+node@24.8.0__picomatch@4.0.3_@types+node@24.8.0", "npm:@tailwindcss/forms@~0.5.10": "0.5.10_tailwindcss@4.1.14", - "npm:@tailwindcss/vite@^4.1.13": "4.1.14_vite@7.1.9__@types+node@24.7.1__picomatch@4.0.3_@types+node@24.7.1", - "npm:@types/node@24": "24.7.1", + "npm:@tailwindcss/vite@^4.1.13": "4.1.14_vite@7.1.10__@types+node@24.8.0__picomatch@4.0.3_@types+node@24.8.0", + "npm:@types/node@24": "24.8.0", "npm:eslint-config-prettier@^10.1.8": "10.1.8_eslint@9.37.0", - "npm:eslint-plugin-svelte@^3.12.4": "3.12.4_eslint@9.37.0_svelte@5.39.11__acorn@8.15.0_postcss@8.5.6", + "npm:eslint-plugin-svelte@^3.12.4": "3.12.4_eslint@9.37.0_svelte@5.40.1__acorn@8.15.0_postcss@8.5.6", "npm:eslint@^9.36.0": "9.37.0", "npm:globals@^16.4.0": "16.4.0", - "npm:prettier-plugin-svelte@^3.4.0": "3.4.0_prettier@3.6.2_svelte@5.39.11__acorn@8.15.0", - "npm:prettier-plugin-tailwindcss@~0.6.14": "0.6.14_prettier@3.6.2_prettier-plugin-svelte@3.4.0__prettier@3.6.2__svelte@5.39.11___acorn@8.15.0_svelte@5.39.11__acorn@8.15.0", + "npm:lru-cache@^11.2.2": "11.2.2", + "npm:prettier-plugin-svelte@^3.4.0": "3.4.0_prettier@3.6.2_svelte@5.40.1__acorn@8.15.0", + "npm:prettier-plugin-tailwindcss@~0.6.14": "0.6.14_prettier@3.6.2_prettier-plugin-svelte@3.4.0__prettier@3.6.2__svelte@5.40.1___acorn@8.15.0_svelte@5.40.1__acorn@8.15.0", "npm:prettier@^3.6.2": "3.6.2", - "npm:svelte-check@^4.3.2": "4.3.3_svelte@5.39.11__acorn@8.15.0_typescript@5.9.3", - "npm:svelte@^5.39.5": "5.39.11_acorn@8.15.0", + "npm:svelte-check@^4.3.2": "4.3.3_svelte@5.40.1__acorn@8.15.0_typescript@5.9.3", + "npm:svelte@^5.39.5": "5.40.1_acorn@8.15.0", "npm:tailwindcss@^4.1.13": "4.1.14", - "npm:typescript-eslint@^8.44.1": "8.46.0_eslint@9.37.0_typescript@5.9.3_@typescript-eslint+parser@8.46.0__eslint@9.37.0__typescript@5.9.3", + "npm:typescript-eslint@^8.44.1": "8.46.1_eslint@9.37.0_typescript@5.9.3_@typescript-eslint+parser@8.46.1__eslint@9.37.0__typescript@5.9.3", "npm:typescript@^5.9.2": "5.9.3", - "npm:vite@^7.1.7": "7.1.9_@types+node@24.7.1_picomatch@4.0.3" + "npm:vite@^7.1.7": "7.1.10_@types+node@24.8.0_picomatch@4.0.3" }, "npm": { - "@esbuild/aix-ppc64@0.25.10": { - "integrity": "sha512-0NFWnA+7l41irNuaSVlLfgNT12caWJVLzp5eAVhZ0z1qpxbockccEt3s+149rE64VUI3Ml2zt8Nv5JVc4QXTsw==", + "@atcute/atproto@3.1.7": { + "integrity": "sha512-3Ym8qaVZg2vf8qw0KO1aue39z/5oik5J+UDoSes1vr8ddw40UVLA5sV4bXSKmLnhzQHiLLgoVZXe4zaKfozPoQ==", + "dependencies": [ + "@atcute/lexicons" + ] + }, + "@atcute/bluesky@3.2.7": { + "integrity": "sha512-mofkZySIIp+Z+TbBD+cDWaPY6FVKNRZG8yhMFkh6uMCuiazDUAUjxr4yaFjYMVcgMN9FkwGllwQJevUH9aTSnQ==", + "dependencies": [ + "@atcute/atproto", + "@atcute/lexicons" + ] + }, + "@atcute/client@4.0.5": { + "integrity": "sha512-R8Qen8goGmEkynYGg2m6XFlVmz0GTDvQ+9w+4QqOob+XMk8/WDpF4aImev7WKEde/rV2gjcqW7zM8E6W9NShDA==", + "dependencies": [ + "@atcute/identity", + "@atcute/lexicons" + ] + }, + "@atcute/identity@1.1.1": { + "integrity": "sha512-zax42n693VEhnC+5tndvO2KLDTMkHOz8UExwmklvJv7R9VujfEwiSWhcv6Jgwb3ellaG8wjiQ1lMOIjLLvwh0Q==", + "dependencies": [ + "@atcute/lexicons", + "@badrap/valita" + ] + }, + "@atcute/lexicons@1.2.2": { + "integrity": "sha512-bgEhJq5Z70/0TbK5sx+tAkrR8FsCODNiL2gUEvS5PuJfPxmFmRYNWaMGehxSPaXWpU2+Oa9ckceHiYbrItDTkA==", + "dependencies": [ + "@standard-schema/spec", + "esm-env" + ] + }, + "@badrap/valita@0.4.6": { + "integrity": "sha512-4kdqcjyxo/8RQ8ayjms47HCWZIF5981oE5nIenbfThKDxWXtEHKipAOWlflpPJzZx9y/JWYQkp18Awr7VuepFg==" + }, + "@esbuild/aix-ppc64@0.25.11": { + "integrity": "sha512-Xt1dOL13m8u0WE8iplx9Ibbm+hFAO0GsU2P34UNoDGvZYkY8ifSiy6Zuc1lYxfG7svWE2fzqCUmFp5HCn51gJg==", "os": ["aix"], "cpu": ["ppc64"] }, - "@esbuild/android-arm64@0.25.10": { - "integrity": "sha512-LSQa7eDahypv/VO6WKohZGPSJDq5OVOo3UoFR1E4t4Gj1W7zEQMUhI+lo81H+DtB+kP+tDgBp+M4oNCwp6kffg==", + "@esbuild/android-arm64@0.25.11": { + "integrity": "sha512-9slpyFBc4FPPz48+f6jyiXOx/Y4v34TUeDDXJpZqAWQn/08lKGeD8aDp9TMn9jDz2CiEuHwfhRmGBvpnd/PWIQ==", "os": ["android"], "cpu": ["arm64"] }, - "@esbuild/android-arm@0.25.10": { - "integrity": "sha512-dQAxF1dW1C3zpeCDc5KqIYuZ1tgAdRXNoZP7vkBIRtKZPYe2xVr/d3SkirklCHudW1B45tGiUlz2pUWDfbDD4w==", + "@esbuild/android-arm@0.25.11": { + "integrity": "sha512-uoa7dU+Dt3HYsethkJ1k6Z9YdcHjTrSb5NUy66ZfZaSV8hEYGD5ZHbEMXnqLFlbBflLsl89Zke7CAdDJ4JI+Gg==", "os": ["android"], "cpu": ["arm"] }, - "@esbuild/android-x64@0.25.10": { - "integrity": "sha512-MiC9CWdPrfhibcXwr39p9ha1x0lZJ9KaVfvzA0Wxwz9ETX4v5CHfF09bx935nHlhi+MxhA63dKRRQLiVgSUtEg==", + "@esbuild/android-x64@0.25.11": { + "integrity": "sha512-Sgiab4xBjPU1QoPEIqS3Xx+R2lezu0LKIEcYe6pftr56PqPygbB7+szVnzoShbx64MUupqoE0KyRlN7gezbl8g==", "os": ["android"], "cpu": ["x64"] }, - "@esbuild/darwin-arm64@0.25.10": { - "integrity": "sha512-JC74bdXcQEpW9KkV326WpZZjLguSZ3DfS8wrrvPMHgQOIEIG/sPXEN/V8IssoJhbefLRcRqw6RQH2NnpdprtMA==", + "@esbuild/darwin-arm64@0.25.11": { + "integrity": "sha512-VekY0PBCukppoQrycFxUqkCojnTQhdec0vevUL/EDOCnXd9LKWqD/bHwMPzigIJXPhC59Vd1WFIL57SKs2mg4w==", "os": ["darwin"], "cpu": ["arm64"] }, - "@esbuild/darwin-x64@0.25.10": { - "integrity": "sha512-tguWg1olF6DGqzws97pKZ8G2L7Ig1vjDmGTwcTuYHbuU6TTjJe5FXbgs5C1BBzHbJ2bo1m3WkQDbWO2PvamRcg==", + "@esbuild/darwin-x64@0.25.11": { + "integrity": "sha512-+hfp3yfBalNEpTGp9loYgbknjR695HkqtY3d3/JjSRUyPg/xd6q+mQqIb5qdywnDxRZykIHs3axEqU6l1+oWEQ==", "os": ["darwin"], "cpu": ["x64"] }, - "@esbuild/freebsd-arm64@0.25.10": { - "integrity": "sha512-3ZioSQSg1HT2N05YxeJWYR+Libe3bREVSdWhEEgExWaDtyFbbXWb49QgPvFH8u03vUPX10JhJPcz7s9t9+boWg==", + "@esbuild/freebsd-arm64@0.25.11": { + "integrity": "sha512-CmKjrnayyTJF2eVuO//uSjl/K3KsMIeYeyN7FyDBjsR3lnSJHaXlVoAK8DZa7lXWChbuOk7NjAc7ygAwrnPBhA==", "os": ["freebsd"], "cpu": ["arm64"] }, - "@esbuild/freebsd-x64@0.25.10": { - "integrity": "sha512-LLgJfHJk014Aa4anGDbh8bmI5Lk+QidDmGzuC2D+vP7mv/GeSN+H39zOf7pN5N8p059FcOfs2bVlrRr4SK9WxA==", + "@esbuild/freebsd-x64@0.25.11": { + "integrity": "sha512-Dyq+5oscTJvMaYPvW3x3FLpi2+gSZTCE/1ffdwuM6G1ARang/mb3jvjxs0mw6n3Lsw84ocfo9CrNMqc5lTfGOw==", "os": ["freebsd"], "cpu": ["x64"] }, - "@esbuild/linux-arm64@0.25.10": { - "integrity": "sha512-5luJWN6YKBsawd5f9i4+c+geYiVEw20FVW5x0v1kEMWNq8UctFjDiMATBxLvmmHA4bf7F6hTRaJgtghFr9iziQ==", + "@esbuild/linux-arm64@0.25.11": { + "integrity": "sha512-Qr8AzcplUhGvdyUF08A1kHU3Vr2O88xxP0Tm8GcdVOUm25XYcMPp2YqSVHbLuXzYQMf9Bh/iKx7YPqECs6ffLA==", "os": ["linux"], "cpu": ["arm64"] }, - "@esbuild/linux-arm@0.25.10": { - "integrity": "sha512-oR31GtBTFYCqEBALI9r6WxoU/ZofZl962pouZRTEYECvNF/dtXKku8YXcJkhgK/beU+zedXfIzHijSRapJY3vg==", + "@esbuild/linux-arm@0.25.11": { + "integrity": "sha512-TBMv6B4kCfrGJ8cUPo7vd6NECZH/8hPpBHHlYI3qzoYFvWu2AdTvZNuU/7hsbKWqu/COU7NIK12dHAAqBLLXgw==", "os": ["linux"], "cpu": ["arm"] }, - "@esbuild/linux-ia32@0.25.10": { - "integrity": "sha512-NrSCx2Kim3EnnWgS4Txn0QGt0Xipoumb6z6sUtl5bOEZIVKhzfyp/Lyw4C1DIYvzeW/5mWYPBFJU3a/8Yr75DQ==", + "@esbuild/linux-ia32@0.25.11": { + "integrity": "sha512-TmnJg8BMGPehs5JKrCLqyWTVAvielc615jbkOirATQvWWB1NMXY77oLMzsUjRLa0+ngecEmDGqt5jiDC6bfvOw==", "os": ["linux"], "cpu": ["ia32"] }, - "@esbuild/linux-loong64@0.25.10": { - "integrity": "sha512-xoSphrd4AZda8+rUDDfD9J6FUMjrkTz8itpTITM4/xgerAZZcFW7Dv+sun7333IfKxGG8gAq+3NbfEMJfiY+Eg==", + "@esbuild/linux-loong64@0.25.11": { + "integrity": "sha512-DIGXL2+gvDaXlaq8xruNXUJdT5tF+SBbJQKbWy/0J7OhU8gOHOzKmGIlfTTl6nHaCOoipxQbuJi7O++ldrxgMw==", "os": ["linux"], "cpu": ["loong64"] }, - "@esbuild/linux-mips64el@0.25.10": { - "integrity": "sha512-ab6eiuCwoMmYDyTnyptoKkVS3k8fy/1Uvq7Dj5czXI6DF2GqD2ToInBI0SHOp5/X1BdZ26RKc5+qjQNGRBelRA==", + "@esbuild/linux-mips64el@0.25.11": { + "integrity": "sha512-Osx1nALUJu4pU43o9OyjSCXokFkFbyzjXb6VhGIJZQ5JZi8ylCQ9/LFagolPsHtgw6himDSyb5ETSfmp4rpiKQ==", "os": ["linux"], "cpu": ["mips64el"] }, - "@esbuild/linux-ppc64@0.25.10": { - "integrity": "sha512-NLinzzOgZQsGpsTkEbdJTCanwA5/wozN9dSgEl12haXJBzMTpssebuXR42bthOF3z7zXFWH1AmvWunUCkBE4EA==", + "@esbuild/linux-ppc64@0.25.11": { + "integrity": "sha512-nbLFgsQQEsBa8XSgSTSlrnBSrpoWh7ioFDUmwo158gIm5NNP+17IYmNWzaIzWmgCxq56vfr34xGkOcZ7jX6CPw==", "os": ["linux"], "cpu": ["ppc64"] }, - "@esbuild/linux-riscv64@0.25.10": { - "integrity": "sha512-FE557XdZDrtX8NMIeA8LBJX3dC2M8VGXwfrQWU7LB5SLOajfJIxmSdyL/gU1m64Zs9CBKvm4UAuBp5aJ8OgnrA==", + "@esbuild/linux-riscv64@0.25.11": { + "integrity": "sha512-HfyAmqZi9uBAbgKYP1yGuI7tSREXwIb438q0nqvlpxAOs3XnZ8RsisRfmVsgV486NdjD7Mw2UrFSw51lzUk1ww==", "os": ["linux"], "cpu": ["riscv64"] }, - "@esbuild/linux-s390x@0.25.10": { - "integrity": "sha512-3BBSbgzuB9ajLoVZk0mGu+EHlBwkusRmeNYdqmznmMc9zGASFjSsxgkNsqmXugpPk00gJ0JNKh/97nxmjctdew==", + "@esbuild/linux-s390x@0.25.11": { + "integrity": "sha512-HjLqVgSSYnVXRisyfmzsH6mXqyvj0SA7pG5g+9W7ESgwA70AXYNpfKBqh1KbTxmQVaYxpzA/SvlB9oclGPbApw==", "os": ["linux"], "cpu": ["s390x"] }, - "@esbuild/linux-x64@0.25.10": { - "integrity": "sha512-QSX81KhFoZGwenVyPoberggdW1nrQZSvfVDAIUXr3WqLRZGZqWk/P4T8p2SP+de2Sr5HPcvjhcJzEiulKgnxtA==", + "@esbuild/linux-x64@0.25.11": { + "integrity": "sha512-HSFAT4+WYjIhrHxKBwGmOOSpphjYkcswF449j6EjsjbinTZbp8PJtjsVK1XFJStdzXdy/jaddAep2FGY+wyFAQ==", "os": ["linux"], "cpu": ["x64"] }, - "@esbuild/netbsd-arm64@0.25.10": { - "integrity": "sha512-AKQM3gfYfSW8XRk8DdMCzaLUFB15dTrZfnX8WXQoOUpUBQ+NaAFCP1kPS/ykbbGYz7rxn0WS48/81l9hFl3u4A==", + "@esbuild/netbsd-arm64@0.25.11": { + "integrity": "sha512-hr9Oxj1Fa4r04dNpWr3P8QKVVsjQhqrMSUzZzf+LZcYjZNqhA3IAfPQdEh1FLVUJSiu6sgAwp3OmwBfbFgG2Xg==", "os": ["netbsd"], "cpu": ["arm64"] }, - "@esbuild/netbsd-x64@0.25.10": { - "integrity": "sha512-7RTytDPGU6fek/hWuN9qQpeGPBZFfB4zZgcz2VK2Z5VpdUxEI8JKYsg3JfO0n/Z1E/6l05n0unDCNc4HnhQGig==", + "@esbuild/netbsd-x64@0.25.11": { + "integrity": "sha512-u7tKA+qbzBydyj0vgpu+5h5AeudxOAGncb8N6C9Kh1N4n7wU1Xw1JDApsRjpShRpXRQlJLb9wY28ELpwdPcZ7A==", "os": ["netbsd"], "cpu": ["x64"] }, - "@esbuild/openbsd-arm64@0.25.10": { - "integrity": "sha512-5Se0VM9Wtq797YFn+dLimf2Zx6McttsH2olUBsDml+lm0GOCRVebRWUvDtkY4BWYv/3NgzS8b/UM3jQNh5hYyw==", + "@esbuild/openbsd-arm64@0.25.11": { + "integrity": "sha512-Qq6YHhayieor3DxFOoYM1q0q1uMFYb7cSpLD2qzDSvK1NAvqFi8Xgivv0cFC6J+hWVw2teCYltyy9/m/14ryHg==", "os": ["openbsd"], "cpu": ["arm64"] }, - "@esbuild/openbsd-x64@0.25.10": { - "integrity": "sha512-XkA4frq1TLj4bEMB+2HnI0+4RnjbuGZfet2gs/LNs5Hc7D89ZQBHQ0gL2ND6Lzu1+QVkjp3x1gIcPKzRNP8bXw==", + "@esbuild/openbsd-x64@0.25.11": { + "integrity": "sha512-CN+7c++kkbrckTOz5hrehxWN7uIhFFlmS/hqziSFVWpAzpWrQoAG4chH+nN3Be+Kzv/uuo7zhX716x3Sn2Jduw==", "os": ["openbsd"], "cpu": ["x64"] }, - "@esbuild/openharmony-arm64@0.25.10": { - "integrity": "sha512-AVTSBhTX8Y/Fz6OmIVBip9tJzZEUcY8WLh7I59+upa5/GPhh2/aM6bvOMQySspnCCHvFi79kMtdJS1w0DXAeag==", + "@esbuild/openharmony-arm64@0.25.11": { + "integrity": "sha512-rOREuNIQgaiR+9QuNkbkxubbp8MSO9rONmwP5nKncnWJ9v5jQ4JxFnLu4zDSRPf3x4u+2VN4pM4RdyIzDty/wQ==", "os": ["openharmony"], "cpu": ["arm64"] }, - "@esbuild/sunos-x64@0.25.10": { - "integrity": "sha512-fswk3XT0Uf2pGJmOpDB7yknqhVkJQkAQOcW/ccVOtfx05LkbWOaRAtn5SaqXypeKQra1QaEa841PgrSL9ubSPQ==", + "@esbuild/sunos-x64@0.25.11": { + "integrity": "sha512-nq2xdYaWxyg9DcIyXkZhcYulC6pQ2FuCgem3LI92IwMgIZ69KHeY8T4Y88pcwoLIjbed8n36CyKoYRDygNSGhA==", "os": ["sunos"], "cpu": ["x64"] }, - "@esbuild/win32-arm64@0.25.10": { - "integrity": "sha512-ah+9b59KDTSfpaCg6VdJoOQvKjI33nTaQr4UluQwW7aEwZQsbMCfTmfEO4VyewOxx4RaDT/xCy9ra2GPWmO7Kw==", + "@esbuild/win32-arm64@0.25.11": { + "integrity": "sha512-3XxECOWJq1qMZ3MN8srCJ/QfoLpL+VaxD/WfNRm1O3B4+AZ/BnLVgFbUV3eiRYDMXetciH16dwPbbHqwe1uU0Q==", "os": ["win32"], "cpu": ["arm64"] }, - "@esbuild/win32-ia32@0.25.10": { - "integrity": "sha512-QHPDbKkrGO8/cz9LKVnJU22HOi4pxZnZhhA2HYHez5Pz4JeffhDjf85E57Oyco163GnzNCVkZK0b/n4Y0UHcSw==", + "@esbuild/win32-ia32@0.25.11": { + "integrity": "sha512-3ukss6gb9XZ8TlRyJlgLn17ecsK4NSQTmdIXRASVsiS2sQ6zPPZklNJT5GR5tE/MUarymmy8kCEf5xPCNCqVOA==", "os": ["win32"], "cpu": ["ia32"] }, - "@esbuild/win32-x64@0.25.10": { - "integrity": "sha512-9KpxSVFCu0iK1owoez6aC/s/EdUQLDN3adTxGCqxMVhrPDj6bt5dbrHDXUuq+Bs2vATFBBrQS5vdQ/Ed2P+nbw==", + "@esbuild/win32-x64@0.25.11": { + "integrity": "sha512-D7Hpz6A2L4hzsRpPaCYkQnGOotdUpDzSGRIv9I+1ITdHROSFUWW95ZPZWQmGka1Fg7W3zFJowyn9WGwMJ0+KPA==", "os": ["win32"], "cpu": ["x64"] }, @@ -409,14 +452,14 @@ "acorn" ] }, - "@sveltejs/adapter-auto@6.1.1_@sveltejs+kit@2.46.4__@sveltejs+vite-plugin-svelte@6.2.1___svelte@5.39.11____acorn@8.15.0___vite@7.1.9____@types+node@24.7.1____picomatch@4.0.3___@types+node@24.7.1__svelte@5.39.11___acorn@8.15.0__vite@7.1.9___@types+node@24.7.1___picomatch@4.0.3__acorn@8.15.0__@types+node@24.7.1_@sveltejs+vite-plugin-svelte@6.2.1__svelte@5.39.11___acorn@8.15.0__vite@7.1.9___@types+node@24.7.1___picomatch@4.0.3__@types+node@24.7.1_svelte@5.39.11__acorn@8.15.0_vite@7.1.9__@types+node@24.7.1__picomatch@4.0.3_@types+node@24.7.1": { + "@sveltejs/adapter-auto@6.1.1_@sveltejs+kit@2.47.0__@sveltejs+vite-plugin-svelte@6.2.1___svelte@5.40.1____acorn@8.15.0___vite@7.1.10____@types+node@24.8.0____picomatch@4.0.3___@types+node@24.8.0__svelte@5.40.1___acorn@8.15.0__vite@7.1.10___@types+node@24.8.0___picomatch@4.0.3__acorn@8.15.0__@types+node@24.8.0_@sveltejs+vite-plugin-svelte@6.2.1__svelte@5.40.1___acorn@8.15.0__vite@7.1.10___@types+node@24.8.0___picomatch@4.0.3__@types+node@24.8.0_svelte@5.40.1__acorn@8.15.0_vite@7.1.10__@types+node@24.8.0__picomatch@4.0.3_@types+node@24.8.0": { "integrity": "sha512-cBNt4jgH4KuaNO5gRSB2CZKkGtz+OCZ8lPjRQGjhvVUD4akotnj2weUia6imLl2v07K3IgsQRyM36909miSwoQ==", "dependencies": [ "@sveltejs/kit" ] }, - "@sveltejs/kit@2.46.4_@sveltejs+vite-plugin-svelte@6.2.1__svelte@5.39.11___acorn@8.15.0__vite@7.1.9___@types+node@24.7.1___picomatch@4.0.3__@types+node@24.7.1_svelte@5.39.11__acorn@8.15.0_vite@7.1.9__@types+node@24.7.1__picomatch@4.0.3_acorn@8.15.0_@types+node@24.7.1": { - "integrity": "sha512-J1fd80WokLzIm6EAV7z7C2+/C02qVAX645LZomARARTRJkbbJSY1Jln3wtBZYibUB8c9/5Z6xqLAV39VdbtWCQ==", + "@sveltejs/kit@2.47.0_@sveltejs+vite-plugin-svelte@6.2.1__svelte@5.40.1___acorn@8.15.0__vite@7.1.10___@types+node@24.8.0___picomatch@4.0.3__@types+node@24.8.0_svelte@5.40.1__acorn@8.15.0_vite@7.1.10__@types+node@24.8.0__picomatch@4.0.3_acorn@8.15.0_@types+node@24.8.0": { + "integrity": "sha512-mznN01MBXtr4T7X/E3ENkhF6GzqxTxL6/whG3OzCzUu8G8KYRNiCdoxLMVWAHJx/mDMPP3XAeKCMZHF/Xd/CDw==", "dependencies": [ "@standard-schema/spec", "@sveltejs/acorn-typescript", @@ -437,7 +480,7 @@ ], "bin": true }, - "@sveltejs/vite-plugin-svelte-inspector@5.0.1_@sveltejs+vite-plugin-svelte@6.2.1__svelte@5.39.11___acorn@8.15.0__vite@7.1.9___@types+node@24.7.1___picomatch@4.0.3__@types+node@24.7.1_svelte@5.39.11__acorn@8.15.0_vite@7.1.9__@types+node@24.7.1__picomatch@4.0.3_@types+node@24.7.1": { + "@sveltejs/vite-plugin-svelte-inspector@5.0.1_@sveltejs+vite-plugin-svelte@6.2.1__svelte@5.40.1___acorn@8.15.0__vite@7.1.10___@types+node@24.8.0___picomatch@4.0.3__@types+node@24.8.0_svelte@5.40.1__acorn@8.15.0_vite@7.1.10__@types+node@24.8.0__picomatch@4.0.3_@types+node@24.8.0": { "integrity": "sha512-ubWshlMk4bc8mkwWbg6vNvCeT7lGQojE3ijDh3QTR6Zr/R+GXxsGbyH4PExEPpiFmqPhYiVSVmHBjUcVc1JIrA==", "dependencies": [ "@sveltejs/vite-plugin-svelte", @@ -446,7 +489,7 @@ "vite" ] }, - "@sveltejs/vite-plugin-svelte@6.2.1_svelte@5.39.11__acorn@8.15.0_vite@7.1.9__@types+node@24.7.1__picomatch@4.0.3_@types+node@24.7.1": { + "@sveltejs/vite-plugin-svelte@6.2.1_svelte@5.40.1__acorn@8.15.0_vite@7.1.10__@types+node@24.8.0__picomatch@4.0.3_@types+node@24.8.0": { "integrity": "sha512-YZs/OSKOQAQCnJvM/P+F1URotNnYNeU3P2s4oIpzm1uFaqUEqRxUB0g5ejMjEb5Gjb9/PiBI5Ktrq4rUUF8UVQ==", "dependencies": [ "@sveltejs/vite-plugin-svelte-inspector", @@ -558,7 +601,7 @@ ], "scripts": true }, - "@tailwindcss/vite@4.1.14_vite@7.1.9__@types+node@24.7.1__picomatch@4.0.3_@types+node@24.7.1": { + "@tailwindcss/vite@4.1.14_vite@7.1.10__@types+node@24.8.0__picomatch@4.0.3_@types+node@24.8.0": { "integrity": "sha512-BoFUoU0XqgCUS1UXWhmDJroKKhNXeDzD7/XwabjkDIAbMnc4ULn5e2FuEuBbhZ6ENZoSYzKlzvZ44Yr6EUDUSA==", "dependencies": [ "@tailwindcss/node", @@ -576,14 +619,14 @@ "@types/json-schema@7.0.15": { "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" }, - "@types/node@24.7.1": { - "integrity": "sha512-CmyhGZanP88uuC5GpWU9q+fI61j2SkhO3UGMUdfYRE6Bcy0ccyzn1Rqj9YAB/ZY4kOXmNf0ocah5GtphmLMP6Q==", + "@types/node@24.8.0": { + "integrity": "sha512-5x08bUtU8hfboMTrJ7mEO4CpepS9yBwAqcL52y86SWNmbPX8LVbNs3EP4cNrIZgdjk2NAlP2ahNihozpoZIxSg==", "dependencies": [ "undici-types" ] }, - "@typescript-eslint/eslint-plugin@8.46.0_@typescript-eslint+parser@8.46.0__eslint@9.37.0__typescript@5.9.3_eslint@9.37.0_typescript@5.9.3": { - "integrity": "sha512-hA8gxBq4ukonVXPy0OKhiaUh/68D0E88GSmtC1iAEnGaieuDi38LhS7jdCHRLi6ErJBNDGCzvh5EnzdPwUc0DA==", + "@typescript-eslint/eslint-plugin@8.46.1_@typescript-eslint+parser@8.46.1__eslint@9.37.0__typescript@5.9.3_eslint@9.37.0_typescript@5.9.3": { + "integrity": "sha512-rUsLh8PXmBjdiPY+Emjz9NX2yHvhS11v0SR6xNJkm5GM1MO9ea/1GoDKlHHZGrOJclL/cZ2i/vRUYVtjRhrHVQ==", "dependencies": [ "@eslint-community/regexpp", "@typescript-eslint/parser", @@ -599,8 +642,8 @@ "typescript" ] }, - "@typescript-eslint/parser@8.46.0_eslint@9.37.0_typescript@5.9.3": { - "integrity": "sha512-n1H6IcDhmmUEG7TNVSspGmiHHutt7iVKtZwRppD7e04wha5MrkV1h3pti9xQLcCMt6YWsncpoT0HMjkH1FNwWQ==", + "@typescript-eslint/parser@8.46.1_eslint@9.37.0_typescript@5.9.3": { + "integrity": "sha512-6JSSaBZmsKvEkbRUkf7Zj7dru/8ZCrJxAqArcLaVMee5907JdtEbKGsZ7zNiIm/UAkpGUkaSMZEXShnN2D1HZA==", "dependencies": [ "@typescript-eslint/scope-manager", "@typescript-eslint/types", @@ -611,8 +654,8 @@ "typescript" ] }, - "@typescript-eslint/project-service@8.46.0_typescript@5.9.3": { - "integrity": "sha512-OEhec0mH+U5Je2NZOeK1AbVCdm0ChyapAyTeXVIYTPXDJ3F07+cu87PPXcGoYqZ7M9YJVvFnfpGg1UmCIqM+QQ==", + "@typescript-eslint/project-service@8.46.1_typescript@5.9.3": { + "integrity": "sha512-FOIaFVMHzRskXr5J4Jp8lFVV0gz5ngv3RHmn+E4HYxSJ3DgDzU7fVI1/M7Ijh1zf6S7HIoaIOtln1H5y8V+9Zg==", "dependencies": [ "@typescript-eslint/tsconfig-utils", "@typescript-eslint/types", @@ -620,21 +663,21 @@ "typescript" ] }, - "@typescript-eslint/scope-manager@8.46.0": { - "integrity": "sha512-lWETPa9XGcBes4jqAMYD9fW0j4n6hrPtTJwWDmtqgFO/4HF4jmdH/Q6wggTw5qIT5TXjKzbt7GsZUBnWoO3dqw==", + "@typescript-eslint/scope-manager@8.46.1": { + "integrity": "sha512-weL9Gg3/5F0pVQKiF8eOXFZp8emqWzZsOJuWRUNtHT+UNV2xSJegmpCNQHy37aEQIbToTq7RHKhWvOsmbM680A==", "dependencies": [ "@typescript-eslint/types", "@typescript-eslint/visitor-keys" ] }, - "@typescript-eslint/tsconfig-utils@8.46.0_typescript@5.9.3": { - "integrity": "sha512-WrYXKGAHY836/N7zoK/kzi6p8tXFhasHh8ocFL9VZSAkvH956gfeRfcnhs3xzRy8qQ/dq3q44v1jvQieMFg2cw==", + "@typescript-eslint/tsconfig-utils@8.46.1_typescript@5.9.3": { + "integrity": "sha512-X88+J/CwFvlJB+mK09VFqx5FE4H5cXD+H/Bdza2aEWkSb8hnWIQorNcscRl4IEo1Cz9VI/+/r/jnGWkbWPx54g==", "dependencies": [ "typescript" ] }, - "@typescript-eslint/type-utils@8.46.0_eslint@9.37.0_typescript@5.9.3": { - "integrity": "sha512-hy+lvYV1lZpVs2jRaEYvgCblZxUoJiPyCemwbQZ+NGulWkQRy0HRPYAoef/CNSzaLt+MLvMptZsHXHlkEilaeg==", + "@typescript-eslint/type-utils@8.46.1_eslint@9.37.0_typescript@5.9.3": { + "integrity": "sha512-+BlmiHIiqufBxkVnOtFwjah/vrkF4MtKKvpXrKSPLCkCtAp8H01/VV43sfqA98Od7nJpDcFnkwgyfQbOG0AMvw==", "dependencies": [ "@typescript-eslint/types", "@typescript-eslint/typescript-estree", @@ -645,11 +688,11 @@ "typescript" ] }, - "@typescript-eslint/types@8.46.0": { - "integrity": "sha512-bHGGJyVjSE4dJJIO5yyEWt/cHyNwga/zXGJbJJ8TiO01aVREK6gCTu3L+5wrkb1FbDkQ+TKjMNe9R/QQQP9+rA==" + "@typescript-eslint/types@8.46.1": { + "integrity": "sha512-C+soprGBHwWBdkDpbaRC4paGBrkIXxVlNohadL5o0kfhsXqOC6GYH2S/Obmig+I0HTDl8wMaRySwrfrXVP8/pQ==" }, - "@typescript-eslint/typescript-estree@8.46.0_typescript@5.9.3": { - "integrity": "sha512-ekDCUfVpAKWJbRfm8T1YRrCot1KFxZn21oV76v5Fj4tr7ELyk84OS+ouvYdcDAwZL89WpEkEj2DKQ+qg//+ucg==", + "@typescript-eslint/typescript-estree@8.46.1_typescript@5.9.3": { + "integrity": "sha512-uIifjT4s8cQKFQ8ZBXXyoUODtRoAd7F7+G8MKmtzj17+1UbdzFl52AzRyZRyKqPHhgzvXunnSckVu36flGy8cg==", "dependencies": [ "@typescript-eslint/project-service", "@typescript-eslint/tsconfig-utils", @@ -664,8 +707,8 @@ "typescript" ] }, - "@typescript-eslint/utils@8.46.0_eslint@9.37.0_typescript@5.9.3": { - "integrity": "sha512-nD6yGWPj1xiOm4Gk0k6hLSZz2XkNXhuYmyIrOWcHoPuAhjT9i5bAG+xbWPgFeNR8HPHHtpNKdYUXJl/D3x7f5g==", + "@typescript-eslint/utils@8.46.1_eslint@9.37.0_typescript@5.9.3": { + "integrity": "sha512-vkYUy6LdZS7q1v/Gxb2Zs7zziuXN0wxqsetJdeZdRe/f5dwJFglmuvZBfTUivCtjH725C1jWCDfpadadD95EDQ==", "dependencies": [ "@eslint-community/eslint-utils", "@typescript-eslint/scope-manager", @@ -675,8 +718,8 @@ "typescript" ] }, - "@typescript-eslint/visitor-keys@8.46.0": { - "integrity": "sha512-FrvMpAK+hTbFy7vH5j1+tMYHMSKLE6RzluFJlkFNKD0p9YsUT75JlBSmr5so3QRzvMwU5/bIEdeNrxm8du8l3Q==", + "@typescript-eslint/visitor-keys@8.46.1": { + "integrity": "sha512-ptkmIf2iDkNUjdeu2bQqhFPV1m6qTnFFjg7PPDjxKWaMaP0Z6I9l30Jr3g5QqbZGdw8YdYvLp+XnqnWWZOg/NA==", "dependencies": [ "@typescript-eslint/types", "eslint-visitor-keys@4.2.1" @@ -802,8 +845,8 @@ "detect-libc@2.1.2": { "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==" }, - "devalue@5.3.2": { - "integrity": "sha512-UDsjUbpQn9kvm68slnrs+mfxwFkIflOhkanmyabZ8zOYk8SMEIbJ3TK+88g70hSIeytu4y18f0z/hYHMTrXIWw==" + "devalue@5.4.1": { + "integrity": "sha512-YtoaOfsqjbZQKGIMRYDWKjUmSB4VJ/RElB+bXZawQAQYAo4xu08GKTMVlsZDTF6R2MbAgjcAQRPI5eIyRAT2OQ==" }, "enhanced-resolve@5.18.3": { "integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==", @@ -812,8 +855,8 @@ "tapable" ] }, - "esbuild@0.25.10": { - "integrity": "sha512-9RiGKvCwaqxO2owP61uQ4BgNborAQskMR6QusfWzQqv7AZOg5oGehdY2pRJMTKuwxd1IDBP4rSbI5lHzU7SMsQ==", + "esbuild@0.25.11": { + "integrity": "sha512-KohQwyzrKTQmhXDW1PjCv3Tyspn9n5GcY2RTDqeORIdIJY8yKIF7sTSopFmn/wpMPW4rdPXI0UE5LJLuq3bx0Q==", "optionalDependencies": [ "@esbuild/aix-ppc64", "@esbuild/android-arm", @@ -855,7 +898,7 @@ ], "bin": true }, - "eslint-plugin-svelte@3.12.4_eslint@9.37.0_svelte@5.39.11__acorn@8.15.0_postcss@8.5.6": { + "eslint-plugin-svelte@3.12.4_eslint@9.37.0_svelte@5.40.1__acorn@8.15.0_postcss@8.5.6": { "integrity": "sha512-hD7wPe+vrPgx3U2X2b/wyTMtWobm660PygMGKrWWYTc9lvtY8DpNFDaU2CJQn1szLjGbn/aJ3g8WiXuKakrEkw==", "dependencies": [ "@eslint-community/eslint-utils", @@ -1218,6 +1261,9 @@ "lodash.merge@4.6.2": { "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" }, + "lru-cache@11.2.2": { + "integrity": "sha512-F9ODfyqML2coTIsQpSkRHnLSZMtkU8Q+mSfcaIyKwy58u+8k5nvAYeiNhsyMARvzNcXJ9QfWVrcPsC9e9rAxtg==" + }, "magic-string@0.30.19": { "integrity": "sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==", "dependencies": [ @@ -1360,14 +1406,14 @@ "prelude-ls@1.2.1": { "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==" }, - "prettier-plugin-svelte@3.4.0_prettier@3.6.2_svelte@5.39.11__acorn@8.15.0": { + "prettier-plugin-svelte@3.4.0_prettier@3.6.2_svelte@5.40.1__acorn@8.15.0": { "integrity": "sha512-pn1ra/0mPObzqoIQn/vUTR3ZZI6UuZ0sHqMK5x2jMLGrs53h0sXhkVuDcrlssHwIMk7FYrMjHBPoUSyyEEDlBQ==", "dependencies": [ "prettier", "svelte" ] }, - "prettier-plugin-tailwindcss@0.6.14_prettier@3.6.2_prettier-plugin-svelte@3.4.0__prettier@3.6.2__svelte@5.39.11___acorn@8.15.0_svelte@5.39.11__acorn@8.15.0": { + "prettier-plugin-tailwindcss@0.6.14_prettier@3.6.2_prettier-plugin-svelte@3.4.0__prettier@3.6.2__svelte@5.40.1___acorn@8.15.0_svelte@5.40.1__acorn@8.15.0": { "integrity": "sha512-pi2e/+ZygeIqntN+vC573BcW5Cve8zUB0SSAGxqpB4f96boZF4M3phPVoOFCeypwkpRYdi7+jQ5YJJUwrkGUAg==", "dependencies": [ "prettier", @@ -1476,7 +1522,7 @@ "has-flag" ] }, - "svelte-check@4.3.3_svelte@5.39.11__acorn@8.15.0_typescript@5.9.3": { + "svelte-check@4.3.3_svelte@5.40.1__acorn@8.15.0_typescript@5.9.3": { "integrity": "sha512-RYP0bEwenDXzfv0P1sKAwjZSlaRyqBn0Fz1TVni58lqyEiqgwztTpmodJrGzP6ZT2aHl4MbTvWP6gbmQ3FOnBg==", "dependencies": [ "@jridgewell/trace-mapping", @@ -1489,7 +1535,7 @@ ], "bin": true }, - "svelte-eslint-parser@1.3.3_svelte@5.39.11__acorn@8.15.0_postcss@8.5.6": { + "svelte-eslint-parser@1.3.3_svelte@5.40.1__acorn@8.15.0_postcss@8.5.6": { "integrity": "sha512-oTrDR8Z7Wnguut7QH3YKh7JR19xv1seB/bz4dxU5J/86eJtZOU4eh0/jZq4dy6tAlz/KROxnkRQspv5ZEt7t+Q==", "dependencies": [ "eslint-scope", @@ -1504,8 +1550,8 @@ "svelte" ] }, - "svelte@5.39.11_acorn@8.15.0": { - "integrity": "sha512-8MxWVm2+3YwrFbPaxOlT1bbMi6OTenrAgks6soZfiaS8Fptk4EVyRIFhJc3RpO264EeSNwgjWAdki0ufg4zkGw==", + "svelte@5.40.1_acorn@8.15.0": { + "integrity": "sha512-0R3t2oiLxJNJb2buz61MNfPdkjeyj2qTCM7TtIv/4ZfF12zD7Ig8iIo+C8febroy+9S4QJ7qfijtearSdO/1ww==", "dependencies": [ "@jridgewell/remapping", "@jridgewell/sourcemap-codec", @@ -1567,8 +1613,8 @@ "prelude-ls" ] }, - "typescript-eslint@8.46.0_eslint@9.37.0_typescript@5.9.3_@typescript-eslint+parser@8.46.0__eslint@9.37.0__typescript@5.9.3": { - "integrity": "sha512-6+ZrB6y2bT2DX3K+Qd9vn7OFOJR+xSLDj+Aw/N3zBwUt27uTw2sw2TE2+UcY1RiyBZkaGbTkVg9SSdPNUG6aUw==", + "typescript-eslint@8.46.1_eslint@9.37.0_typescript@5.9.3_@typescript-eslint+parser@8.46.1__eslint@9.37.0__typescript@5.9.3": { + "integrity": "sha512-VHgijW803JafdSsDO8I761r3SHrgk4T00IdyQ+/UsthtgPRsBWQLqoSxOolxTpxRKi1kGXK0bSz4CoAc9ObqJA==", "dependencies": [ "@typescript-eslint/eslint-plugin", "@typescript-eslint/parser", @@ -1594,8 +1640,8 @@ "util-deprecate@1.0.2": { "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, - "vite@7.1.9_@types+node@24.7.1_picomatch@4.0.3": { - "integrity": "sha512-4nVGliEpxmhCL8DslSAUdxlB6+SMrhB0a1v5ijlh1xB1nEPuy1mxaHxysVucLHuWryAxLWg6a5ei+U4TLn/rFg==", + "vite@7.1.10_@types+node@24.8.0_picomatch@4.0.3": { + "integrity": "sha512-CmuvUBzVJ/e3HGxhg6cYk88NGgTnBoOo7ogtfJJ0fefUWAxN/WDSUa50o+oVBxuIhO8FoEZW0j2eW7sfjs5EtA==", "dependencies": [ "@types/node", "esbuild", @@ -1613,7 +1659,7 @@ ], "bin": true }, - "vitefu@1.1.1_vite@7.1.9__@types+node@24.7.1__picomatch@4.0.3_@types+node@24.7.1": { + "vitefu@1.1.1_vite@7.1.10__@types+node@24.8.0__picomatch@4.0.3_@types+node@24.8.0": { "integrity": "sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ==", "dependencies": [ "vite" @@ -1648,6 +1694,11 @@ "workspace": { "packageJson": { "dependencies": [ + "npm:@atcute/atproto@^3.1.7", + "npm:@atcute/bluesky@^3.2.7", + "npm:@atcute/client@^4.0.5", + "npm:@atcute/identity@^1.1.1", + "npm:@atcute/lexicons@^1.2.2", "npm:@eslint/compat@^1.4.0", "npm:@eslint/js@^9.36.0", "npm:@sveltejs/adapter-auto@^6.1.0", @@ -1660,6 +1711,7 @@ "npm:eslint-plugin-svelte@^3.12.4", "npm:eslint@^9.36.0", "npm:globals@^16.4.0", + "npm:lru-cache@^11.2.2", "npm:prettier-plugin-svelte@^3.4.0", "npm:prettier-plugin-tailwindcss@~0.6.14", "npm:prettier@^3.6.2", diff --git a/env.d.ts b/env.d.ts new file mode 100644 index 0000000..4362229 --- /dev/null +++ b/env.d.ts @@ -0,0 +1,2 @@ +import type {} from '@atcute/atproto'; +import type {} from '@atcute/bluesky'; diff --git a/package.json b/package.json index b715065..2451544 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,14 @@ "format": "prettier --write .", "lint": "prettier --check . && eslint ." }, + "dependencies": { + "@atcute/atproto": "^3.1.7", + "@atcute/bluesky": "^3.2.7", + "@atcute/client": "^4.0.5", + "@atcute/identity": "^1.1.1", + "@atcute/lexicons": "^1.2.2", + "lru-cache": "^11.2.2" + }, "devDependencies": { "@eslint/compat": "^1.4.0", "@eslint/js": "^9.36.0", diff --git a/src/components/BskyPost.svelte b/src/components/BskyPost.svelte new file mode 100644 index 0000000..fd5fcfc --- /dev/null +++ b/src/components/BskyPost.svelte @@ -0,0 +1,44 @@ + + +{#await post} + loading post... +{:then post} + {#if post.ok} + {@const record = post.value} + {identifier} - [{record.embed ? getEmbedText(record.embed.$type) : null}] + {record.text} + {:else} + error fetching post: {post.error} + {/if} +{/await} diff --git a/src/components/PostComposer.svelte b/src/components/PostComposer.svelte new file mode 100644 index 0000000..25d9779 --- /dev/null +++ b/src/components/PostComposer.svelte @@ -0,0 +1,68 @@ + + +
+ {#if info.length > 0} + {info} + {/if} +
+ + +
+
diff --git a/src/lib/at/client.ts b/src/lib/at/client.ts new file mode 100644 index 0000000..cbdad4e --- /dev/null +++ b/src/lib/at/client.ts @@ -0,0 +1,167 @@ +import { err, map, ok, type Result } from '$lib/result'; +import { ComAtprotoIdentityResolveIdentity, ComAtprotoRepoGetRecord } from '@atcute/atproto'; +import { Client as AtcuteClient, CredentialManager } from '@atcute/client'; +import { safeParse, type Handle, type InferOutput } from '@atcute/lexicons'; +import type { ActorIdentifier, AtprotoDid, Nsid, RecordKey } from '@atcute/lexicons/syntax'; +import type { + InferXRPCBodyOutput, + ObjectSchema, + RecordKeySchema, + RecordSchema, + XRPCQueryMetadata +} from '@atcute/lexicons/validations'; +import * as v from '@atcute/lexicons/validations'; +import { LRUCache } from 'lru-cache'; + +export const MiniDocQuery = v.query('com.bad-example.identity.resolveMiniDoc', { + params: v.object({ + identifier: v.actorIdentifierString() + }), + output: { + type: 'lex', + schema: v.object({ + did: v.didString(), + handle: v.handleString(), + pds: v.genericUriString(), + signing_key: v.string() + }) + } +}); +export type MiniDoc = InferOutput; + +const cacheTtl = 1000 * 60 * 60 * 24; +const handleCache = new LRUCache({ + max: 1000, + ttl: cacheTtl +}); +const didDocCache = new LRUCache({ + max: 1000, + ttl: cacheTtl +}); +const recordCache = new LRUCache< + string, + InferOutput +>({ + max: 5000, + ttl: cacheTtl +}); + +export class AtpClient { + public atcute: AtcuteClient | null = null; + public didDoc: MiniDoc | null = null; + + private slingshotUrl: URL = new URL('https://slingshot.microcosm.blue'); + private spacedustUrl: URL = new URL('https://spacedust.microcosm.blue'); + + async login(handle: Handle, password: string): Promise> { + const didDoc = await this.resolveDidDoc(handle); + if (!didDoc.ok) return err(didDoc.error); + this.didDoc = didDoc.value; + + try { + const handler = new CredentialManager({ service: didDoc.value.pds }); + const rpc = new AtcuteClient({ handler }); + await handler.login({ identifier: didDoc.value.did, password }); + + this.atcute = rpc; + } catch (error) { + return err(`failed to login: ${error}`); + } + + return ok(null); + } + + async getRecord< + Collection extends Nsid, + TObject extends ObjectSchema & { shape: { $type: v.LiteralSchema } }, + TKey extends RecordKeySchema, + Schema extends RecordSchema, + Output extends InferOutput + >(schema: Schema, repo: ActorIdentifier, rkey: RecordKey): Promise> { + const collection = schema.object.shape.$type.expected; + const cacheKey = `${repo}:${collection}:${rkey}`; + + const cached = recordCache.get(cacheKey); + if (cached) return ok(cached.value as Output); + + const result = await fetchMicrocosm(this.slingshotUrl, ComAtprotoRepoGetRecord.mainSchema, { + repo, + collection, + rkey + }); + + if (!result.ok) return result; + // console.info(`fetched record:`, result.value); + + const parsed = safeParse(schema, result.value.value); + if (!parsed.ok) return err(parsed.message); + + recordCache.set(cacheKey, result.value); + + return ok(parsed.value as Output); + } + + async resolveHandle(handle: Handle): Promise> { + const cached = handleCache.get(handle); + if (cached) return ok(cached); + + const res = await fetchMicrocosm( + this.slingshotUrl, + ComAtprotoIdentityResolveIdentity.mainSchema, + { + handle: handle + } + ); + + const mapped = map(res, (data) => data.did as AtprotoDid); + + if (mapped.ok) { + handleCache.set(handle, mapped.value); + } + + return mapped; + } + + async resolveDidDoc(handleOrDid: ActorIdentifier): Promise> { + const cached = didDocCache.get(handleOrDid); + if (cached) return ok(cached); + + const result = await fetchMicrocosm(this.slingshotUrl, MiniDocQuery, { + identifier: handleOrDid + }); + + if (result.ok) { + didDocCache.set(handleOrDid, result.value); + } + + return result; + } +} + +const fetchMicrocosm = async < + Schema extends XRPCQueryMetadata, + Output extends InferXRPCBodyOutput +>( + api: URL, + schema: Schema, + params?: URLSearchParams | Record, + init?: RequestInit +): Promise> => { + if (!schema.output || schema.output.type === 'blob') return err('schema must be blob'); + if (params && !(params instanceof URLSearchParams)) params = new URLSearchParams(params); + if (params?.size === 0) params = undefined; + try { + api.pathname = `/xrpc/${schema.nsid}`; + api.search = params ? `?${params}` : ''; + // console.info(`fetching:`, api.href); + const response = await fetch(api, init); + const body = await response.json(); + if (response.status === 400) return err(`${body.error}: ${body.message}`); + if (response.status !== 200) return err(`UnexpectedStatusCode: ${response.status}`); + const parsed = safeParse(schema.output.schema, body); + if (!parsed.ok) return err(parsed.message); + return ok(parsed.value as Output); + } catch (error) { + return err(`FetchError: ${error}`); + } +}; diff --git a/src/lib/at/fetch.ts b/src/lib/at/fetch.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/lib/index.ts b/src/lib/index.ts index 856f2b6..1f3348e 100644 --- a/src/lib/index.ts +++ b/src/lib/index.ts @@ -1 +1,3 @@ -// place files you want to import through the `$lib` alias in this folder. +import { AtpClient } from './at/client'; + +export const client = new AtpClient(); diff --git a/src/lib/result.ts b/src/lib/result.ts new file mode 100644 index 0000000..d29b251 --- /dev/null +++ b/src/lib/result.ts @@ -0,0 +1,28 @@ +export type Result = + | { + ok: true; + value: T; + } + | { + ok: false; + error: E; + }; + +export const ok = (value: T): Result => { + return { ok: true, value }; +}; +export const err = (error: E): Result => { + return { ok: false, error }; +}; +export const expect = (v: Result, msg: string = 'expected result to not be error:') => { + if (v.ok) { + return v.value; + } + throw `${msg} ${v.error}`; +}; +export const map = (v: Result, fn: (value: T) => U): Result => { + if (v.ok) { + return ok(fn(v.value)); + } + return err(v.error); +}; diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index cc88df0..d1ce12d 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -1,2 +1,11 @@ -

Welcome to SvelteKit

-

Visit svelte.dev/docs/kit to read the documentation

+ + +
+ +
+ +
diff --git a/svelte.config.js b/svelte.config.js index 1295460..1a3bb8b 100644 --- a/svelte.config.js +++ b/svelte.config.js @@ -5,13 +5,25 @@ import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; const config = { // Consult https://svelte.dev/docs/kit/integrations // for more information about preprocessors - preprocess: vitePreprocess(), + preprocess: [vitePreprocess()], kit: { // adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list. // If your environment is not supported, or you settled on a specific environment, switch out the adapter. // See https://svelte.dev/docs/kit/adapters for more information about adapters. - adapter: adapter() + adapter: adapter(), + alias: { + $lib: 'src/lib', + '$lib/*': 'src/lib/*', + $components: 'src/components', + '$components/*': 'src/components/*' + } + }, + + compilerOptions: { + experimental: { + async: true + } } }; diff --git a/tsconfig.json b/tsconfig.json index a5567ee..0d8ce8e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -9,7 +9,14 @@ "skipLibCheck": true, "sourceMap": true, "strict": true, - "moduleResolution": "bundler" + "moduleResolution": "bundler", + "jsx": "react-jsx", + "paths": { + "$components": ["./src/components"], + "$components/*": ["./src/components/*"], + "$lib": ["./src/lib"], + "$lib/*": ["./src/lib/*"] + } } // Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias // except $lib which is handled by https://svelte.dev/docs/kit/configuration#files