replies timeline only, appview-less bluesky client

feat: implement client and fetching

+160 -108
deno.lock
··· 1 { 2 "version": "5", 3 "specifiers": { 4 "npm:@eslint/compat@^1.4.0": "1.4.0_eslint@9.37.0", 5 "npm:@eslint/js@^9.36.0": "9.37.0", 6 - "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", 7 - "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", 8 - "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", 9 "npm:@tailwindcss/forms@~0.5.10": "0.5.10_tailwindcss@4.1.14", 10 - "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", 11 - "npm:@types/node@24": "24.7.1", 12 "npm:eslint-config-prettier@^10.1.8": "10.1.8_eslint@9.37.0", 13 - "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", 14 "npm:eslint@^9.36.0": "9.37.0", 15 "npm:globals@^16.4.0": "16.4.0", 16 - "npm:prettier-plugin-svelte@^3.4.0": "3.4.0_prettier@3.6.2_svelte@5.39.11__acorn@8.15.0", 17 - "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", 18 "npm:prettier@^3.6.2": "3.6.2", 19 - "npm:svelte-check@^4.3.2": "4.3.3_svelte@5.39.11__acorn@8.15.0_typescript@5.9.3", 20 - "npm:svelte@^5.39.5": "5.39.11_acorn@8.15.0", 21 "npm:tailwindcss@^4.1.13": "4.1.14", 22 - "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", 23 "npm:typescript@^5.9.2": "5.9.3", 24 - "npm:vite@^7.1.7": "7.1.9_@types+node@24.7.1_picomatch@4.0.3" 25 }, 26 "npm": { 27 - "@esbuild/aix-ppc64@0.25.10": { 28 - "integrity": "sha512-0NFWnA+7l41irNuaSVlLfgNT12caWJVLzp5eAVhZ0z1qpxbockccEt3s+149rE64VUI3Ml2zt8Nv5JVc4QXTsw==", 29 "os": ["aix"], 30 "cpu": ["ppc64"] 31 }, 32 - "@esbuild/android-arm64@0.25.10": { 33 - "integrity": "sha512-LSQa7eDahypv/VO6WKohZGPSJDq5OVOo3UoFR1E4t4Gj1W7zEQMUhI+lo81H+DtB+kP+tDgBp+M4oNCwp6kffg==", 34 "os": ["android"], 35 "cpu": ["arm64"] 36 }, 37 - "@esbuild/android-arm@0.25.10": { 38 - "integrity": "sha512-dQAxF1dW1C3zpeCDc5KqIYuZ1tgAdRXNoZP7vkBIRtKZPYe2xVr/d3SkirklCHudW1B45tGiUlz2pUWDfbDD4w==", 39 "os": ["android"], 40 "cpu": ["arm"] 41 }, 42 - "@esbuild/android-x64@0.25.10": { 43 - "integrity": "sha512-MiC9CWdPrfhibcXwr39p9ha1x0lZJ9KaVfvzA0Wxwz9ETX4v5CHfF09bx935nHlhi+MxhA63dKRRQLiVgSUtEg==", 44 "os": ["android"], 45 "cpu": ["x64"] 46 }, 47 - "@esbuild/darwin-arm64@0.25.10": { 48 - "integrity": "sha512-JC74bdXcQEpW9KkV326WpZZjLguSZ3DfS8wrrvPMHgQOIEIG/sPXEN/V8IssoJhbefLRcRqw6RQH2NnpdprtMA==", 49 "os": ["darwin"], 50 "cpu": ["arm64"] 51 }, 52 - "@esbuild/darwin-x64@0.25.10": { 53 - "integrity": "sha512-tguWg1olF6DGqzws97pKZ8G2L7Ig1vjDmGTwcTuYHbuU6TTjJe5FXbgs5C1BBzHbJ2bo1m3WkQDbWO2PvamRcg==", 54 "os": ["darwin"], 55 "cpu": ["x64"] 56 }, 57 - "@esbuild/freebsd-arm64@0.25.10": { 58 - "integrity": "sha512-3ZioSQSg1HT2N05YxeJWYR+Libe3bREVSdWhEEgExWaDtyFbbXWb49QgPvFH8u03vUPX10JhJPcz7s9t9+boWg==", 59 "os": ["freebsd"], 60 "cpu": ["arm64"] 61 }, 62 - "@esbuild/freebsd-x64@0.25.10": { 63 - "integrity": "sha512-LLgJfHJk014Aa4anGDbh8bmI5Lk+QidDmGzuC2D+vP7mv/GeSN+H39zOf7pN5N8p059FcOfs2bVlrRr4SK9WxA==", 64 "os": ["freebsd"], 65 "cpu": ["x64"] 66 }, 67 - "@esbuild/linux-arm64@0.25.10": { 68 - "integrity": "sha512-5luJWN6YKBsawd5f9i4+c+geYiVEw20FVW5x0v1kEMWNq8UctFjDiMATBxLvmmHA4bf7F6hTRaJgtghFr9iziQ==", 69 "os": ["linux"], 70 "cpu": ["arm64"] 71 }, 72 - "@esbuild/linux-arm@0.25.10": { 73 - "integrity": "sha512-oR31GtBTFYCqEBALI9r6WxoU/ZofZl962pouZRTEYECvNF/dtXKku8YXcJkhgK/beU+zedXfIzHijSRapJY3vg==", 74 "os": ["linux"], 75 "cpu": ["arm"] 76 }, 77 - "@esbuild/linux-ia32@0.25.10": { 78 - "integrity": "sha512-NrSCx2Kim3EnnWgS4Txn0QGt0Xipoumb6z6sUtl5bOEZIVKhzfyp/Lyw4C1DIYvzeW/5mWYPBFJU3a/8Yr75DQ==", 79 "os": ["linux"], 80 "cpu": ["ia32"] 81 }, 82 - "@esbuild/linux-loong64@0.25.10": { 83 - "integrity": "sha512-xoSphrd4AZda8+rUDDfD9J6FUMjrkTz8itpTITM4/xgerAZZcFW7Dv+sun7333IfKxGG8gAq+3NbfEMJfiY+Eg==", 84 "os": ["linux"], 85 "cpu": ["loong64"] 86 }, 87 - "@esbuild/linux-mips64el@0.25.10": { 88 - "integrity": "sha512-ab6eiuCwoMmYDyTnyptoKkVS3k8fy/1Uvq7Dj5czXI6DF2GqD2ToInBI0SHOp5/X1BdZ26RKc5+qjQNGRBelRA==", 89 "os": ["linux"], 90 "cpu": ["mips64el"] 91 }, 92 - "@esbuild/linux-ppc64@0.25.10": { 93 - "integrity": "sha512-NLinzzOgZQsGpsTkEbdJTCanwA5/wozN9dSgEl12haXJBzMTpssebuXR42bthOF3z7zXFWH1AmvWunUCkBE4EA==", 94 "os": ["linux"], 95 "cpu": ["ppc64"] 96 }, 97 - "@esbuild/linux-riscv64@0.25.10": { 98 - "integrity": "sha512-FE557XdZDrtX8NMIeA8LBJX3dC2M8VGXwfrQWU7LB5SLOajfJIxmSdyL/gU1m64Zs9CBKvm4UAuBp5aJ8OgnrA==", 99 "os": ["linux"], 100 "cpu": ["riscv64"] 101 }, 102 - "@esbuild/linux-s390x@0.25.10": { 103 - "integrity": "sha512-3BBSbgzuB9ajLoVZk0mGu+EHlBwkusRmeNYdqmznmMc9zGASFjSsxgkNsqmXugpPk00gJ0JNKh/97nxmjctdew==", 104 "os": ["linux"], 105 "cpu": ["s390x"] 106 }, 107 - "@esbuild/linux-x64@0.25.10": { 108 - "integrity": "sha512-QSX81KhFoZGwenVyPoberggdW1nrQZSvfVDAIUXr3WqLRZGZqWk/P4T8p2SP+de2Sr5HPcvjhcJzEiulKgnxtA==", 109 "os": ["linux"], 110 "cpu": ["x64"] 111 }, 112 - "@esbuild/netbsd-arm64@0.25.10": { 113 - "integrity": "sha512-AKQM3gfYfSW8XRk8DdMCzaLUFB15dTrZfnX8WXQoOUpUBQ+NaAFCP1kPS/ykbbGYz7rxn0WS48/81l9hFl3u4A==", 114 "os": ["netbsd"], 115 "cpu": ["arm64"] 116 }, 117 - "@esbuild/netbsd-x64@0.25.10": { 118 - "integrity": "sha512-7RTytDPGU6fek/hWuN9qQpeGPBZFfB4zZgcz2VK2Z5VpdUxEI8JKYsg3JfO0n/Z1E/6l05n0unDCNc4HnhQGig==", 119 "os": ["netbsd"], 120 "cpu": ["x64"] 121 }, 122 - "@esbuild/openbsd-arm64@0.25.10": { 123 - "integrity": "sha512-5Se0VM9Wtq797YFn+dLimf2Zx6McttsH2olUBsDml+lm0GOCRVebRWUvDtkY4BWYv/3NgzS8b/UM3jQNh5hYyw==", 124 "os": ["openbsd"], 125 "cpu": ["arm64"] 126 }, 127 - "@esbuild/openbsd-x64@0.25.10": { 128 - "integrity": "sha512-XkA4frq1TLj4bEMB+2HnI0+4RnjbuGZfet2gs/LNs5Hc7D89ZQBHQ0gL2ND6Lzu1+QVkjp3x1gIcPKzRNP8bXw==", 129 "os": ["openbsd"], 130 "cpu": ["x64"] 131 }, 132 - "@esbuild/openharmony-arm64@0.25.10": { 133 - "integrity": "sha512-AVTSBhTX8Y/Fz6OmIVBip9tJzZEUcY8WLh7I59+upa5/GPhh2/aM6bvOMQySspnCCHvFi79kMtdJS1w0DXAeag==", 134 "os": ["openharmony"], 135 "cpu": ["arm64"] 136 }, 137 - "@esbuild/sunos-x64@0.25.10": { 138 - "integrity": "sha512-fswk3XT0Uf2pGJmOpDB7yknqhVkJQkAQOcW/ccVOtfx05LkbWOaRAtn5SaqXypeKQra1QaEa841PgrSL9ubSPQ==", 139 "os": ["sunos"], 140 "cpu": ["x64"] 141 }, 142 - "@esbuild/win32-arm64@0.25.10": { 143 - "integrity": "sha512-ah+9b59KDTSfpaCg6VdJoOQvKjI33nTaQr4UluQwW7aEwZQsbMCfTmfEO4VyewOxx4RaDT/xCy9ra2GPWmO7Kw==", 144 "os": ["win32"], 145 "cpu": ["arm64"] 146 }, 147 - "@esbuild/win32-ia32@0.25.10": { 148 - "integrity": "sha512-QHPDbKkrGO8/cz9LKVnJU22HOi4pxZnZhhA2HYHez5Pz4JeffhDjf85E57Oyco163GnzNCVkZK0b/n4Y0UHcSw==", 149 "os": ["win32"], 150 "cpu": ["ia32"] 151 }, 152 - "@esbuild/win32-x64@0.25.10": { 153 - "integrity": "sha512-9KpxSVFCu0iK1owoez6aC/s/EdUQLDN3adTxGCqxMVhrPDj6bt5dbrHDXUuq+Bs2vATFBBrQS5vdQ/Ed2P+nbw==", 154 "os": ["win32"], 155 "cpu": ["x64"] 156 }, ··· 409 "acorn" 410 ] 411 }, 412 - "@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": { 413 "integrity": "sha512-cBNt4jgH4KuaNO5gRSB2CZKkGtz+OCZ8lPjRQGjhvVUD4akotnj2weUia6imLl2v07K3IgsQRyM36909miSwoQ==", 414 "dependencies": [ 415 "@sveltejs/kit" 416 ] 417 }, 418 - "@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": { 419 - "integrity": "sha512-J1fd80WokLzIm6EAV7z7C2+/C02qVAX645LZomARARTRJkbbJSY1Jln3wtBZYibUB8c9/5Z6xqLAV39VdbtWCQ==", 420 "dependencies": [ 421 "@standard-schema/spec", 422 "@sveltejs/acorn-typescript", ··· 437 ], 438 "bin": true 439 }, 440 - "@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": { 441 "integrity": "sha512-ubWshlMk4bc8mkwWbg6vNvCeT7lGQojE3ijDh3QTR6Zr/R+GXxsGbyH4PExEPpiFmqPhYiVSVmHBjUcVc1JIrA==", 442 "dependencies": [ 443 "@sveltejs/vite-plugin-svelte", ··· 446 "vite" 447 ] 448 }, 449 - "@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": { 450 "integrity": "sha512-YZs/OSKOQAQCnJvM/P+F1URotNnYNeU3P2s4oIpzm1uFaqUEqRxUB0g5ejMjEb5Gjb9/PiBI5Ktrq4rUUF8UVQ==", 451 "dependencies": [ 452 "@sveltejs/vite-plugin-svelte-inspector", ··· 558 ], 559 "scripts": true 560 }, 561 - "@tailwindcss/vite@4.1.14_vite@7.1.9__@types+node@24.7.1__picomatch@4.0.3_@types+node@24.7.1": { 562 "integrity": "sha512-BoFUoU0XqgCUS1UXWhmDJroKKhNXeDzD7/XwabjkDIAbMnc4ULn5e2FuEuBbhZ6ENZoSYzKlzvZ44Yr6EUDUSA==", 563 "dependencies": [ 564 "@tailwindcss/node", ··· 576 "@types/json-schema@7.0.15": { 577 "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" 578 }, 579 - "@types/node@24.7.1": { 580 - "integrity": "sha512-CmyhGZanP88uuC5GpWU9q+fI61j2SkhO3UGMUdfYRE6Bcy0ccyzn1Rqj9YAB/ZY4kOXmNf0ocah5GtphmLMP6Q==", 581 "dependencies": [ 582 "undici-types" 583 ] 584 }, 585 - "@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": { 586 - "integrity": "sha512-hA8gxBq4ukonVXPy0OKhiaUh/68D0E88GSmtC1iAEnGaieuDi38LhS7jdCHRLi6ErJBNDGCzvh5EnzdPwUc0DA==", 587 "dependencies": [ 588 "@eslint-community/regexpp", 589 "@typescript-eslint/parser", ··· 599 "typescript" 600 ] 601 }, 602 - "@typescript-eslint/parser@8.46.0_eslint@9.37.0_typescript@5.9.3": { 603 - "integrity": "sha512-n1H6IcDhmmUEG7TNVSspGmiHHutt7iVKtZwRppD7e04wha5MrkV1h3pti9xQLcCMt6YWsncpoT0HMjkH1FNwWQ==", 604 "dependencies": [ 605 "@typescript-eslint/scope-manager", 606 "@typescript-eslint/types", ··· 611 "typescript" 612 ] 613 }, 614 - "@typescript-eslint/project-service@8.46.0_typescript@5.9.3": { 615 - "integrity": "sha512-OEhec0mH+U5Je2NZOeK1AbVCdm0ChyapAyTeXVIYTPXDJ3F07+cu87PPXcGoYqZ7M9YJVvFnfpGg1UmCIqM+QQ==", 616 "dependencies": [ 617 "@typescript-eslint/tsconfig-utils", 618 "@typescript-eslint/types", ··· 620 "typescript" 621 ] 622 }, 623 - "@typescript-eslint/scope-manager@8.46.0": { 624 - "integrity": "sha512-lWETPa9XGcBes4jqAMYD9fW0j4n6hrPtTJwWDmtqgFO/4HF4jmdH/Q6wggTw5qIT5TXjKzbt7GsZUBnWoO3dqw==", 625 "dependencies": [ 626 "@typescript-eslint/types", 627 "@typescript-eslint/visitor-keys" 628 ] 629 }, 630 - "@typescript-eslint/tsconfig-utils@8.46.0_typescript@5.9.3": { 631 - "integrity": "sha512-WrYXKGAHY836/N7zoK/kzi6p8tXFhasHh8ocFL9VZSAkvH956gfeRfcnhs3xzRy8qQ/dq3q44v1jvQieMFg2cw==", 632 "dependencies": [ 633 "typescript" 634 ] 635 }, 636 - "@typescript-eslint/type-utils@8.46.0_eslint@9.37.0_typescript@5.9.3": { 637 - "integrity": "sha512-hy+lvYV1lZpVs2jRaEYvgCblZxUoJiPyCemwbQZ+NGulWkQRy0HRPYAoef/CNSzaLt+MLvMptZsHXHlkEilaeg==", 638 "dependencies": [ 639 "@typescript-eslint/types", 640 "@typescript-eslint/typescript-estree", ··· 645 "typescript" 646 ] 647 }, 648 - "@typescript-eslint/types@8.46.0": { 649 - "integrity": "sha512-bHGGJyVjSE4dJJIO5yyEWt/cHyNwga/zXGJbJJ8TiO01aVREK6gCTu3L+5wrkb1FbDkQ+TKjMNe9R/QQQP9+rA==" 650 }, 651 - "@typescript-eslint/typescript-estree@8.46.0_typescript@5.9.3": { 652 - "integrity": "sha512-ekDCUfVpAKWJbRfm8T1YRrCot1KFxZn21oV76v5Fj4tr7ELyk84OS+ouvYdcDAwZL89WpEkEj2DKQ+qg//+ucg==", 653 "dependencies": [ 654 "@typescript-eslint/project-service", 655 "@typescript-eslint/tsconfig-utils", ··· 664 "typescript" 665 ] 666 }, 667 - "@typescript-eslint/utils@8.46.0_eslint@9.37.0_typescript@5.9.3": { 668 - "integrity": "sha512-nD6yGWPj1xiOm4Gk0k6hLSZz2XkNXhuYmyIrOWcHoPuAhjT9i5bAG+xbWPgFeNR8HPHHtpNKdYUXJl/D3x7f5g==", 669 "dependencies": [ 670 "@eslint-community/eslint-utils", 671 "@typescript-eslint/scope-manager", ··· 675 "typescript" 676 ] 677 }, 678 - "@typescript-eslint/visitor-keys@8.46.0": { 679 - "integrity": "sha512-FrvMpAK+hTbFy7vH5j1+tMYHMSKLE6RzluFJlkFNKD0p9YsUT75JlBSmr5so3QRzvMwU5/bIEdeNrxm8du8l3Q==", 680 "dependencies": [ 681 "@typescript-eslint/types", 682 "eslint-visitor-keys@4.2.1" ··· 802 "detect-libc@2.1.2": { 803 "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==" 804 }, 805 - "devalue@5.3.2": { 806 - "integrity": "sha512-UDsjUbpQn9kvm68slnrs+mfxwFkIflOhkanmyabZ8zOYk8SMEIbJ3TK+88g70hSIeytu4y18f0z/hYHMTrXIWw==" 807 }, 808 "enhanced-resolve@5.18.3": { 809 "integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==", ··· 812 "tapable" 813 ] 814 }, 815 - "esbuild@0.25.10": { 816 - "integrity": "sha512-9RiGKvCwaqxO2owP61uQ4BgNborAQskMR6QusfWzQqv7AZOg5oGehdY2pRJMTKuwxd1IDBP4rSbI5lHzU7SMsQ==", 817 "optionalDependencies": [ 818 "@esbuild/aix-ppc64", 819 "@esbuild/android-arm", ··· 855 ], 856 "bin": true 857 }, 858 - "eslint-plugin-svelte@3.12.4_eslint@9.37.0_svelte@5.39.11__acorn@8.15.0_postcss@8.5.6": { 859 "integrity": "sha512-hD7wPe+vrPgx3U2X2b/wyTMtWobm660PygMGKrWWYTc9lvtY8DpNFDaU2CJQn1szLjGbn/aJ3g8WiXuKakrEkw==", 860 "dependencies": [ 861 "@eslint-community/eslint-utils", ··· 1218 "lodash.merge@4.6.2": { 1219 "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" 1220 }, 1221 "magic-string@0.30.19": { 1222 "integrity": "sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==", 1223 "dependencies": [ ··· 1360 "prelude-ls@1.2.1": { 1361 "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==" 1362 }, 1363 - "prettier-plugin-svelte@3.4.0_prettier@3.6.2_svelte@5.39.11__acorn@8.15.0": { 1364 "integrity": "sha512-pn1ra/0mPObzqoIQn/vUTR3ZZI6UuZ0sHqMK5x2jMLGrs53h0sXhkVuDcrlssHwIMk7FYrMjHBPoUSyyEEDlBQ==", 1365 "dependencies": [ 1366 "prettier", 1367 "svelte" 1368 ] 1369 }, 1370 - "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": { 1371 "integrity": "sha512-pi2e/+ZygeIqntN+vC573BcW5Cve8zUB0SSAGxqpB4f96boZF4M3phPVoOFCeypwkpRYdi7+jQ5YJJUwrkGUAg==", 1372 "dependencies": [ 1373 "prettier", ··· 1476 "has-flag" 1477 ] 1478 }, 1479 - "svelte-check@4.3.3_svelte@5.39.11__acorn@8.15.0_typescript@5.9.3": { 1480 "integrity": "sha512-RYP0bEwenDXzfv0P1sKAwjZSlaRyqBn0Fz1TVni58lqyEiqgwztTpmodJrGzP6ZT2aHl4MbTvWP6gbmQ3FOnBg==", 1481 "dependencies": [ 1482 "@jridgewell/trace-mapping", ··· 1489 ], 1490 "bin": true 1491 }, 1492 - "svelte-eslint-parser@1.3.3_svelte@5.39.11__acorn@8.15.0_postcss@8.5.6": { 1493 "integrity": "sha512-oTrDR8Z7Wnguut7QH3YKh7JR19xv1seB/bz4dxU5J/86eJtZOU4eh0/jZq4dy6tAlz/KROxnkRQspv5ZEt7t+Q==", 1494 "dependencies": [ 1495 "eslint-scope", ··· 1504 "svelte" 1505 ] 1506 }, 1507 - "svelte@5.39.11_acorn@8.15.0": { 1508 - "integrity": "sha512-8MxWVm2+3YwrFbPaxOlT1bbMi6OTenrAgks6soZfiaS8Fptk4EVyRIFhJc3RpO264EeSNwgjWAdki0ufg4zkGw==", 1509 "dependencies": [ 1510 "@jridgewell/remapping", 1511 "@jridgewell/sourcemap-codec", ··· 1567 "prelude-ls" 1568 ] 1569 }, 1570 - "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": { 1571 - "integrity": "sha512-6+ZrB6y2bT2DX3K+Qd9vn7OFOJR+xSLDj+Aw/N3zBwUt27uTw2sw2TE2+UcY1RiyBZkaGbTkVg9SSdPNUG6aUw==", 1572 "dependencies": [ 1573 "@typescript-eslint/eslint-plugin", 1574 "@typescript-eslint/parser", ··· 1594 "util-deprecate@1.0.2": { 1595 "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" 1596 }, 1597 - "vite@7.1.9_@types+node@24.7.1_picomatch@4.0.3": { 1598 - "integrity": "sha512-4nVGliEpxmhCL8DslSAUdxlB6+SMrhB0a1v5ijlh1xB1nEPuy1mxaHxysVucLHuWryAxLWg6a5ei+U4TLn/rFg==", 1599 "dependencies": [ 1600 "@types/node", 1601 "esbuild", ··· 1613 ], 1614 "bin": true 1615 }, 1616 - "vitefu@1.1.1_vite@7.1.9__@types+node@24.7.1__picomatch@4.0.3_@types+node@24.7.1": { 1617 "integrity": "sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ==", 1618 "dependencies": [ 1619 "vite" ··· 1648 "workspace": { 1649 "packageJson": { 1650 "dependencies": [ 1651 "npm:@eslint/compat@^1.4.0", 1652 "npm:@eslint/js@^9.36.0", 1653 "npm:@sveltejs/adapter-auto@^6.1.0", ··· 1660 "npm:eslint-plugin-svelte@^3.12.4", 1661 "npm:eslint@^9.36.0", 1662 "npm:globals@^16.4.0", 1663 "npm:prettier-plugin-svelte@^3.4.0", 1664 "npm:prettier-plugin-tailwindcss@~0.6.14", 1665 "npm:prettier@^3.6.2",
··· 1 { 2 "version": "5", 3 "specifiers": { 4 + "npm:@atcute/atproto@^3.1.7": "3.1.7", 5 + "npm:@atcute/bluesky@^3.2.7": "3.2.7", 6 + "npm:@atcute/client@^4.0.5": "4.0.5", 7 + "npm:@atcute/identity@^1.1.1": "1.1.1", 8 + "npm:@atcute/lexicons@^1.2.2": "1.2.2", 9 "npm:@eslint/compat@^1.4.0": "1.4.0_eslint@9.37.0", 10 "npm:@eslint/js@^9.36.0": "9.37.0", 11 + "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", 12 + "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", 13 + "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", 14 "npm:@tailwindcss/forms@~0.5.10": "0.5.10_tailwindcss@4.1.14", 15 + "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", 16 + "npm:@types/node@24": "24.8.0", 17 "npm:eslint-config-prettier@^10.1.8": "10.1.8_eslint@9.37.0", 18 + "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", 19 "npm:eslint@^9.36.0": "9.37.0", 20 "npm:globals@^16.4.0": "16.4.0", 21 + "npm:lru-cache@^11.2.2": "11.2.2", 22 + "npm:prettier-plugin-svelte@^3.4.0": "3.4.0_prettier@3.6.2_svelte@5.40.1__acorn@8.15.0", 23 + "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", 24 "npm:prettier@^3.6.2": "3.6.2", 25 + "npm:svelte-check@^4.3.2": "4.3.3_svelte@5.40.1__acorn@8.15.0_typescript@5.9.3", 26 + "npm:svelte@^5.39.5": "5.40.1_acorn@8.15.0", 27 "npm:tailwindcss@^4.1.13": "4.1.14", 28 + "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", 29 "npm:typescript@^5.9.2": "5.9.3", 30 + "npm:vite@^7.1.7": "7.1.10_@types+node@24.8.0_picomatch@4.0.3" 31 }, 32 "npm": { 33 + "@atcute/atproto@3.1.7": { 34 + "integrity": "sha512-3Ym8qaVZg2vf8qw0KO1aue39z/5oik5J+UDoSes1vr8ddw40UVLA5sV4bXSKmLnhzQHiLLgoVZXe4zaKfozPoQ==", 35 + "dependencies": [ 36 + "@atcute/lexicons" 37 + ] 38 + }, 39 + "@atcute/bluesky@3.2.7": { 40 + "integrity": "sha512-mofkZySIIp+Z+TbBD+cDWaPY6FVKNRZG8yhMFkh6uMCuiazDUAUjxr4yaFjYMVcgMN9FkwGllwQJevUH9aTSnQ==", 41 + "dependencies": [ 42 + "@atcute/atproto", 43 + "@atcute/lexicons" 44 + ] 45 + }, 46 + "@atcute/client@4.0.5": { 47 + "integrity": "sha512-R8Qen8goGmEkynYGg2m6XFlVmz0GTDvQ+9w+4QqOob+XMk8/WDpF4aImev7WKEde/rV2gjcqW7zM8E6W9NShDA==", 48 + "dependencies": [ 49 + "@atcute/identity", 50 + "@atcute/lexicons" 51 + ] 52 + }, 53 + "@atcute/identity@1.1.1": { 54 + "integrity": "sha512-zax42n693VEhnC+5tndvO2KLDTMkHOz8UExwmklvJv7R9VujfEwiSWhcv6Jgwb3ellaG8wjiQ1lMOIjLLvwh0Q==", 55 + "dependencies": [ 56 + "@atcute/lexicons", 57 + "@badrap/valita" 58 + ] 59 + }, 60 + "@atcute/lexicons@1.2.2": { 61 + "integrity": "sha512-bgEhJq5Z70/0TbK5sx+tAkrR8FsCODNiL2gUEvS5PuJfPxmFmRYNWaMGehxSPaXWpU2+Oa9ckceHiYbrItDTkA==", 62 + "dependencies": [ 63 + "@standard-schema/spec", 64 + "esm-env" 65 + ] 66 + }, 67 + "@badrap/valita@0.4.6": { 68 + "integrity": "sha512-4kdqcjyxo/8RQ8ayjms47HCWZIF5981oE5nIenbfThKDxWXtEHKipAOWlflpPJzZx9y/JWYQkp18Awr7VuepFg==" 69 + }, 70 + "@esbuild/aix-ppc64@0.25.11": { 71 + "integrity": "sha512-Xt1dOL13m8u0WE8iplx9Ibbm+hFAO0GsU2P34UNoDGvZYkY8ifSiy6Zuc1lYxfG7svWE2fzqCUmFp5HCn51gJg==", 72 "os": ["aix"], 73 "cpu": ["ppc64"] 74 }, 75 + "@esbuild/android-arm64@0.25.11": { 76 + "integrity": "sha512-9slpyFBc4FPPz48+f6jyiXOx/Y4v34TUeDDXJpZqAWQn/08lKGeD8aDp9TMn9jDz2CiEuHwfhRmGBvpnd/PWIQ==", 77 "os": ["android"], 78 "cpu": ["arm64"] 79 }, 80 + "@esbuild/android-arm@0.25.11": { 81 + "integrity": "sha512-uoa7dU+Dt3HYsethkJ1k6Z9YdcHjTrSb5NUy66ZfZaSV8hEYGD5ZHbEMXnqLFlbBflLsl89Zke7CAdDJ4JI+Gg==", 82 "os": ["android"], 83 "cpu": ["arm"] 84 }, 85 + "@esbuild/android-x64@0.25.11": { 86 + "integrity": "sha512-Sgiab4xBjPU1QoPEIqS3Xx+R2lezu0LKIEcYe6pftr56PqPygbB7+szVnzoShbx64MUupqoE0KyRlN7gezbl8g==", 87 "os": ["android"], 88 "cpu": ["x64"] 89 }, 90 + "@esbuild/darwin-arm64@0.25.11": { 91 + "integrity": "sha512-VekY0PBCukppoQrycFxUqkCojnTQhdec0vevUL/EDOCnXd9LKWqD/bHwMPzigIJXPhC59Vd1WFIL57SKs2mg4w==", 92 "os": ["darwin"], 93 "cpu": ["arm64"] 94 }, 95 + "@esbuild/darwin-x64@0.25.11": { 96 + "integrity": "sha512-+hfp3yfBalNEpTGp9loYgbknjR695HkqtY3d3/JjSRUyPg/xd6q+mQqIb5qdywnDxRZykIHs3axEqU6l1+oWEQ==", 97 "os": ["darwin"], 98 "cpu": ["x64"] 99 }, 100 + "@esbuild/freebsd-arm64@0.25.11": { 101 + "integrity": "sha512-CmKjrnayyTJF2eVuO//uSjl/K3KsMIeYeyN7FyDBjsR3lnSJHaXlVoAK8DZa7lXWChbuOk7NjAc7ygAwrnPBhA==", 102 "os": ["freebsd"], 103 "cpu": ["arm64"] 104 }, 105 + "@esbuild/freebsd-x64@0.25.11": { 106 + "integrity": "sha512-Dyq+5oscTJvMaYPvW3x3FLpi2+gSZTCE/1ffdwuM6G1ARang/mb3jvjxs0mw6n3Lsw84ocfo9CrNMqc5lTfGOw==", 107 "os": ["freebsd"], 108 "cpu": ["x64"] 109 }, 110 + "@esbuild/linux-arm64@0.25.11": { 111 + "integrity": "sha512-Qr8AzcplUhGvdyUF08A1kHU3Vr2O88xxP0Tm8GcdVOUm25XYcMPp2YqSVHbLuXzYQMf9Bh/iKx7YPqECs6ffLA==", 112 "os": ["linux"], 113 "cpu": ["arm64"] 114 }, 115 + "@esbuild/linux-arm@0.25.11": { 116 + "integrity": "sha512-TBMv6B4kCfrGJ8cUPo7vd6NECZH/8hPpBHHlYI3qzoYFvWu2AdTvZNuU/7hsbKWqu/COU7NIK12dHAAqBLLXgw==", 117 "os": ["linux"], 118 "cpu": ["arm"] 119 }, 120 + "@esbuild/linux-ia32@0.25.11": { 121 + "integrity": "sha512-TmnJg8BMGPehs5JKrCLqyWTVAvielc615jbkOirATQvWWB1NMXY77oLMzsUjRLa0+ngecEmDGqt5jiDC6bfvOw==", 122 "os": ["linux"], 123 "cpu": ["ia32"] 124 }, 125 + "@esbuild/linux-loong64@0.25.11": { 126 + "integrity": "sha512-DIGXL2+gvDaXlaq8xruNXUJdT5tF+SBbJQKbWy/0J7OhU8gOHOzKmGIlfTTl6nHaCOoipxQbuJi7O++ldrxgMw==", 127 "os": ["linux"], 128 "cpu": ["loong64"] 129 }, 130 + "@esbuild/linux-mips64el@0.25.11": { 131 + "integrity": "sha512-Osx1nALUJu4pU43o9OyjSCXokFkFbyzjXb6VhGIJZQ5JZi8ylCQ9/LFagolPsHtgw6himDSyb5ETSfmp4rpiKQ==", 132 "os": ["linux"], 133 "cpu": ["mips64el"] 134 }, 135 + "@esbuild/linux-ppc64@0.25.11": { 136 + "integrity": "sha512-nbLFgsQQEsBa8XSgSTSlrnBSrpoWh7ioFDUmwo158gIm5NNP+17IYmNWzaIzWmgCxq56vfr34xGkOcZ7jX6CPw==", 137 "os": ["linux"], 138 "cpu": ["ppc64"] 139 }, 140 + "@esbuild/linux-riscv64@0.25.11": { 141 + "integrity": "sha512-HfyAmqZi9uBAbgKYP1yGuI7tSREXwIb438q0nqvlpxAOs3XnZ8RsisRfmVsgV486NdjD7Mw2UrFSw51lzUk1ww==", 142 "os": ["linux"], 143 "cpu": ["riscv64"] 144 }, 145 + "@esbuild/linux-s390x@0.25.11": { 146 + "integrity": "sha512-HjLqVgSSYnVXRisyfmzsH6mXqyvj0SA7pG5g+9W7ESgwA70AXYNpfKBqh1KbTxmQVaYxpzA/SvlB9oclGPbApw==", 147 "os": ["linux"], 148 "cpu": ["s390x"] 149 }, 150 + "@esbuild/linux-x64@0.25.11": { 151 + "integrity": "sha512-HSFAT4+WYjIhrHxKBwGmOOSpphjYkcswF449j6EjsjbinTZbp8PJtjsVK1XFJStdzXdy/jaddAep2FGY+wyFAQ==", 152 "os": ["linux"], 153 "cpu": ["x64"] 154 }, 155 + "@esbuild/netbsd-arm64@0.25.11": { 156 + "integrity": "sha512-hr9Oxj1Fa4r04dNpWr3P8QKVVsjQhqrMSUzZzf+LZcYjZNqhA3IAfPQdEh1FLVUJSiu6sgAwp3OmwBfbFgG2Xg==", 157 "os": ["netbsd"], 158 "cpu": ["arm64"] 159 }, 160 + "@esbuild/netbsd-x64@0.25.11": { 161 + "integrity": "sha512-u7tKA+qbzBydyj0vgpu+5h5AeudxOAGncb8N6C9Kh1N4n7wU1Xw1JDApsRjpShRpXRQlJLb9wY28ELpwdPcZ7A==", 162 "os": ["netbsd"], 163 "cpu": ["x64"] 164 }, 165 + "@esbuild/openbsd-arm64@0.25.11": { 166 + "integrity": "sha512-Qq6YHhayieor3DxFOoYM1q0q1uMFYb7cSpLD2qzDSvK1NAvqFi8Xgivv0cFC6J+hWVw2teCYltyy9/m/14ryHg==", 167 "os": ["openbsd"], 168 "cpu": ["arm64"] 169 }, 170 + "@esbuild/openbsd-x64@0.25.11": { 171 + "integrity": "sha512-CN+7c++kkbrckTOz5hrehxWN7uIhFFlmS/hqziSFVWpAzpWrQoAG4chH+nN3Be+Kzv/uuo7zhX716x3Sn2Jduw==", 172 "os": ["openbsd"], 173 "cpu": ["x64"] 174 }, 175 + "@esbuild/openharmony-arm64@0.25.11": { 176 + "integrity": "sha512-rOREuNIQgaiR+9QuNkbkxubbp8MSO9rONmwP5nKncnWJ9v5jQ4JxFnLu4zDSRPf3x4u+2VN4pM4RdyIzDty/wQ==", 177 "os": ["openharmony"], 178 "cpu": ["arm64"] 179 }, 180 + "@esbuild/sunos-x64@0.25.11": { 181 + "integrity": "sha512-nq2xdYaWxyg9DcIyXkZhcYulC6pQ2FuCgem3LI92IwMgIZ69KHeY8T4Y88pcwoLIjbed8n36CyKoYRDygNSGhA==", 182 "os": ["sunos"], 183 "cpu": ["x64"] 184 }, 185 + "@esbuild/win32-arm64@0.25.11": { 186 + "integrity": "sha512-3XxECOWJq1qMZ3MN8srCJ/QfoLpL+VaxD/WfNRm1O3B4+AZ/BnLVgFbUV3eiRYDMXetciH16dwPbbHqwe1uU0Q==", 187 "os": ["win32"], 188 "cpu": ["arm64"] 189 }, 190 + "@esbuild/win32-ia32@0.25.11": { 191 + "integrity": "sha512-3ukss6gb9XZ8TlRyJlgLn17ecsK4NSQTmdIXRASVsiS2sQ6zPPZklNJT5GR5tE/MUarymmy8kCEf5xPCNCqVOA==", 192 "os": ["win32"], 193 "cpu": ["ia32"] 194 }, 195 + "@esbuild/win32-x64@0.25.11": { 196 + "integrity": "sha512-D7Hpz6A2L4hzsRpPaCYkQnGOotdUpDzSGRIv9I+1ITdHROSFUWW95ZPZWQmGka1Fg7W3zFJowyn9WGwMJ0+KPA==", 197 "os": ["win32"], 198 "cpu": ["x64"] 199 }, ··· 452 "acorn" 453 ] 454 }, 455 + "@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": { 456 "integrity": "sha512-cBNt4jgH4KuaNO5gRSB2CZKkGtz+OCZ8lPjRQGjhvVUD4akotnj2weUia6imLl2v07K3IgsQRyM36909miSwoQ==", 457 "dependencies": [ 458 "@sveltejs/kit" 459 ] 460 }, 461 + "@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": { 462 + "integrity": "sha512-mznN01MBXtr4T7X/E3ENkhF6GzqxTxL6/whG3OzCzUu8G8KYRNiCdoxLMVWAHJx/mDMPP3XAeKCMZHF/Xd/CDw==", 463 "dependencies": [ 464 "@standard-schema/spec", 465 "@sveltejs/acorn-typescript", ··· 480 ], 481 "bin": true 482 }, 483 + "@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": { 484 "integrity": "sha512-ubWshlMk4bc8mkwWbg6vNvCeT7lGQojE3ijDh3QTR6Zr/R+GXxsGbyH4PExEPpiFmqPhYiVSVmHBjUcVc1JIrA==", 485 "dependencies": [ 486 "@sveltejs/vite-plugin-svelte", ··· 489 "vite" 490 ] 491 }, 492 + "@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": { 493 "integrity": "sha512-YZs/OSKOQAQCnJvM/P+F1URotNnYNeU3P2s4oIpzm1uFaqUEqRxUB0g5ejMjEb5Gjb9/PiBI5Ktrq4rUUF8UVQ==", 494 "dependencies": [ 495 "@sveltejs/vite-plugin-svelte-inspector", ··· 601 ], 602 "scripts": true 603 }, 604 + "@tailwindcss/vite@4.1.14_vite@7.1.10__@types+node@24.8.0__picomatch@4.0.3_@types+node@24.8.0": { 605 "integrity": "sha512-BoFUoU0XqgCUS1UXWhmDJroKKhNXeDzD7/XwabjkDIAbMnc4ULn5e2FuEuBbhZ6ENZoSYzKlzvZ44Yr6EUDUSA==", 606 "dependencies": [ 607 "@tailwindcss/node", ··· 619 "@types/json-schema@7.0.15": { 620 "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" 621 }, 622 + "@types/node@24.8.0": { 623 + "integrity": "sha512-5x08bUtU8hfboMTrJ7mEO4CpepS9yBwAqcL52y86SWNmbPX8LVbNs3EP4cNrIZgdjk2NAlP2ahNihozpoZIxSg==", 624 "dependencies": [ 625 "undici-types" 626 ] 627 }, 628 + "@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": { 629 + "integrity": "sha512-rUsLh8PXmBjdiPY+Emjz9NX2yHvhS11v0SR6xNJkm5GM1MO9ea/1GoDKlHHZGrOJclL/cZ2i/vRUYVtjRhrHVQ==", 630 "dependencies": [ 631 "@eslint-community/regexpp", 632 "@typescript-eslint/parser", ··· 642 "typescript" 643 ] 644 }, 645 + "@typescript-eslint/parser@8.46.1_eslint@9.37.0_typescript@5.9.3": { 646 + "integrity": "sha512-6JSSaBZmsKvEkbRUkf7Zj7dru/8ZCrJxAqArcLaVMee5907JdtEbKGsZ7zNiIm/UAkpGUkaSMZEXShnN2D1HZA==", 647 "dependencies": [ 648 "@typescript-eslint/scope-manager", 649 "@typescript-eslint/types", ··· 654 "typescript" 655 ] 656 }, 657 + "@typescript-eslint/project-service@8.46.1_typescript@5.9.3": { 658 + "integrity": "sha512-FOIaFVMHzRskXr5J4Jp8lFVV0gz5ngv3RHmn+E4HYxSJ3DgDzU7fVI1/M7Ijh1zf6S7HIoaIOtln1H5y8V+9Zg==", 659 "dependencies": [ 660 "@typescript-eslint/tsconfig-utils", 661 "@typescript-eslint/types", ··· 663 "typescript" 664 ] 665 }, 666 + "@typescript-eslint/scope-manager@8.46.1": { 667 + "integrity": "sha512-weL9Gg3/5F0pVQKiF8eOXFZp8emqWzZsOJuWRUNtHT+UNV2xSJegmpCNQHy37aEQIbToTq7RHKhWvOsmbM680A==", 668 "dependencies": [ 669 "@typescript-eslint/types", 670 "@typescript-eslint/visitor-keys" 671 ] 672 }, 673 + "@typescript-eslint/tsconfig-utils@8.46.1_typescript@5.9.3": { 674 + "integrity": "sha512-X88+J/CwFvlJB+mK09VFqx5FE4H5cXD+H/Bdza2aEWkSb8hnWIQorNcscRl4IEo1Cz9VI/+/r/jnGWkbWPx54g==", 675 "dependencies": [ 676 "typescript" 677 ] 678 }, 679 + "@typescript-eslint/type-utils@8.46.1_eslint@9.37.0_typescript@5.9.3": { 680 + "integrity": "sha512-+BlmiHIiqufBxkVnOtFwjah/vrkF4MtKKvpXrKSPLCkCtAp8H01/VV43sfqA98Od7nJpDcFnkwgyfQbOG0AMvw==", 681 "dependencies": [ 682 "@typescript-eslint/types", 683 "@typescript-eslint/typescript-estree", ··· 688 "typescript" 689 ] 690 }, 691 + "@typescript-eslint/types@8.46.1": { 692 + "integrity": "sha512-C+soprGBHwWBdkDpbaRC4paGBrkIXxVlNohadL5o0kfhsXqOC6GYH2S/Obmig+I0HTDl8wMaRySwrfrXVP8/pQ==" 693 }, 694 + "@typescript-eslint/typescript-estree@8.46.1_typescript@5.9.3": { 695 + "integrity": "sha512-uIifjT4s8cQKFQ8ZBXXyoUODtRoAd7F7+G8MKmtzj17+1UbdzFl52AzRyZRyKqPHhgzvXunnSckVu36flGy8cg==", 696 "dependencies": [ 697 "@typescript-eslint/project-service", 698 "@typescript-eslint/tsconfig-utils", ··· 707 "typescript" 708 ] 709 }, 710 + "@typescript-eslint/utils@8.46.1_eslint@9.37.0_typescript@5.9.3": { 711 + "integrity": "sha512-vkYUy6LdZS7q1v/Gxb2Zs7zziuXN0wxqsetJdeZdRe/f5dwJFglmuvZBfTUivCtjH725C1jWCDfpadadD95EDQ==", 712 "dependencies": [ 713 "@eslint-community/eslint-utils", 714 "@typescript-eslint/scope-manager", ··· 718 "typescript" 719 ] 720 }, 721 + "@typescript-eslint/visitor-keys@8.46.1": { 722 + "integrity": "sha512-ptkmIf2iDkNUjdeu2bQqhFPV1m6qTnFFjg7PPDjxKWaMaP0Z6I9l30Jr3g5QqbZGdw8YdYvLp+XnqnWWZOg/NA==", 723 "dependencies": [ 724 "@typescript-eslint/types", 725 "eslint-visitor-keys@4.2.1" ··· 845 "detect-libc@2.1.2": { 846 "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==" 847 }, 848 + "devalue@5.4.1": { 849 + "integrity": "sha512-YtoaOfsqjbZQKGIMRYDWKjUmSB4VJ/RElB+bXZawQAQYAo4xu08GKTMVlsZDTF6R2MbAgjcAQRPI5eIyRAT2OQ==" 850 }, 851 "enhanced-resolve@5.18.3": { 852 "integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==", ··· 855 "tapable" 856 ] 857 }, 858 + "esbuild@0.25.11": { 859 + "integrity": "sha512-KohQwyzrKTQmhXDW1PjCv3Tyspn9n5GcY2RTDqeORIdIJY8yKIF7sTSopFmn/wpMPW4rdPXI0UE5LJLuq3bx0Q==", 860 "optionalDependencies": [ 861 "@esbuild/aix-ppc64", 862 "@esbuild/android-arm", ··· 898 ], 899 "bin": true 900 }, 901 + "eslint-plugin-svelte@3.12.4_eslint@9.37.0_svelte@5.40.1__acorn@8.15.0_postcss@8.5.6": { 902 "integrity": "sha512-hD7wPe+vrPgx3U2X2b/wyTMtWobm660PygMGKrWWYTc9lvtY8DpNFDaU2CJQn1szLjGbn/aJ3g8WiXuKakrEkw==", 903 "dependencies": [ 904 "@eslint-community/eslint-utils", ··· 1261 "lodash.merge@4.6.2": { 1262 "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" 1263 }, 1264 + "lru-cache@11.2.2": { 1265 + "integrity": "sha512-F9ODfyqML2coTIsQpSkRHnLSZMtkU8Q+mSfcaIyKwy58u+8k5nvAYeiNhsyMARvzNcXJ9QfWVrcPsC9e9rAxtg==" 1266 + }, 1267 "magic-string@0.30.19": { 1268 "integrity": "sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==", 1269 "dependencies": [ ··· 1406 "prelude-ls@1.2.1": { 1407 "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==" 1408 }, 1409 + "prettier-plugin-svelte@3.4.0_prettier@3.6.2_svelte@5.40.1__acorn@8.15.0": { 1410 "integrity": "sha512-pn1ra/0mPObzqoIQn/vUTR3ZZI6UuZ0sHqMK5x2jMLGrs53h0sXhkVuDcrlssHwIMk7FYrMjHBPoUSyyEEDlBQ==", 1411 "dependencies": [ 1412 "prettier", 1413 "svelte" 1414 ] 1415 }, 1416 + "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": { 1417 "integrity": "sha512-pi2e/+ZygeIqntN+vC573BcW5Cve8zUB0SSAGxqpB4f96boZF4M3phPVoOFCeypwkpRYdi7+jQ5YJJUwrkGUAg==", 1418 "dependencies": [ 1419 "prettier", ··· 1522 "has-flag" 1523 ] 1524 }, 1525 + "svelte-check@4.3.3_svelte@5.40.1__acorn@8.15.0_typescript@5.9.3": { 1526 "integrity": "sha512-RYP0bEwenDXzfv0P1sKAwjZSlaRyqBn0Fz1TVni58lqyEiqgwztTpmodJrGzP6ZT2aHl4MbTvWP6gbmQ3FOnBg==", 1527 "dependencies": [ 1528 "@jridgewell/trace-mapping", ··· 1535 ], 1536 "bin": true 1537 }, 1538 + "svelte-eslint-parser@1.3.3_svelte@5.40.1__acorn@8.15.0_postcss@8.5.6": { 1539 "integrity": "sha512-oTrDR8Z7Wnguut7QH3YKh7JR19xv1seB/bz4dxU5J/86eJtZOU4eh0/jZq4dy6tAlz/KROxnkRQspv5ZEt7t+Q==", 1540 "dependencies": [ 1541 "eslint-scope", ··· 1550 "svelte" 1551 ] 1552 }, 1553 + "svelte@5.40.1_acorn@8.15.0": { 1554 + "integrity": "sha512-0R3t2oiLxJNJb2buz61MNfPdkjeyj2qTCM7TtIv/4ZfF12zD7Ig8iIo+C8febroy+9S4QJ7qfijtearSdO/1ww==", 1555 "dependencies": [ 1556 "@jridgewell/remapping", 1557 "@jridgewell/sourcemap-codec", ··· 1613 "prelude-ls" 1614 ] 1615 }, 1616 + "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": { 1617 + "integrity": "sha512-VHgijW803JafdSsDO8I761r3SHrgk4T00IdyQ+/UsthtgPRsBWQLqoSxOolxTpxRKi1kGXK0bSz4CoAc9ObqJA==", 1618 "dependencies": [ 1619 "@typescript-eslint/eslint-plugin", 1620 "@typescript-eslint/parser", ··· 1640 "util-deprecate@1.0.2": { 1641 "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" 1642 }, 1643 + "vite@7.1.10_@types+node@24.8.0_picomatch@4.0.3": { 1644 + "integrity": "sha512-CmuvUBzVJ/e3HGxhg6cYk88NGgTnBoOo7ogtfJJ0fefUWAxN/WDSUa50o+oVBxuIhO8FoEZW0j2eW7sfjs5EtA==", 1645 "dependencies": [ 1646 "@types/node", 1647 "esbuild", ··· 1659 ], 1660 "bin": true 1661 }, 1662 + "vitefu@1.1.1_vite@7.1.10__@types+node@24.8.0__picomatch@4.0.3_@types+node@24.8.0": { 1663 "integrity": "sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ==", 1664 "dependencies": [ 1665 "vite" ··· 1694 "workspace": { 1695 "packageJson": { 1696 "dependencies": [ 1697 + "npm:@atcute/atproto@^3.1.7", 1698 + "npm:@atcute/bluesky@^3.2.7", 1699 + "npm:@atcute/client@^4.0.5", 1700 + "npm:@atcute/identity@^1.1.1", 1701 + "npm:@atcute/lexicons@^1.2.2", 1702 "npm:@eslint/compat@^1.4.0", 1703 "npm:@eslint/js@^9.36.0", 1704 "npm:@sveltejs/adapter-auto@^6.1.0", ··· 1711 "npm:eslint-plugin-svelte@^3.12.4", 1712 "npm:eslint@^9.36.0", 1713 "npm:globals@^16.4.0", 1714 + "npm:lru-cache@^11.2.2", 1715 "npm:prettier-plugin-svelte@^3.4.0", 1716 "npm:prettier-plugin-tailwindcss@~0.6.14", 1717 "npm:prettier@^3.6.2",
+2
env.d.ts
···
··· 1 + import type {} from '@atcute/atproto'; 2 + import type {} from '@atcute/bluesky';
+8
package.json
··· 13 "format": "prettier --write .", 14 "lint": "prettier --check . && eslint ." 15 }, 16 "devDependencies": { 17 "@eslint/compat": "^1.4.0", 18 "@eslint/js": "^9.36.0",
··· 13 "format": "prettier --write .", 14 "lint": "prettier --check . && eslint ." 15 }, 16 + "dependencies": { 17 + "@atcute/atproto": "^3.1.7", 18 + "@atcute/bluesky": "^3.2.7", 19 + "@atcute/client": "^4.0.5", 20 + "@atcute/identity": "^1.1.1", 21 + "@atcute/lexicons": "^1.2.2", 22 + "lru-cache": "^11.2.2" 23 + }, 24 "devDependencies": { 25 "@eslint/compat": "^1.4.0", 26 "@eslint/js": "^9.36.0",
+44
src/components/BskyPost.svelte
···
··· 1 + <script lang="ts"> 2 + import type { AtpClient } from '$lib/at/client'; 3 + import { AppBskyFeedPost } from '@atcute/bluesky'; 4 + import type { ActorIdentifier, RecordKey } from '@atcute/lexicons'; 5 + 6 + interface Props { 7 + client: AtpClient; 8 + identifier: ActorIdentifier; 9 + rkey: RecordKey; 10 + } 11 + 12 + const { client, identifier, rkey }: Props = $props(); 13 + 14 + const post = client.getRecord(AppBskyFeedPost.mainSchema, identifier, rkey); 15 + 16 + const getEmbedText = (embedType: string) => { 17 + switch (embedType) { 18 + case 'app.bsky.embed.external': 19 + return 'contains external link'; 20 + case 'app.bsky.embed.record': 21 + return 'quotes post'; 22 + case 'app.bsky.embed.images': 23 + return 'contains images'; 24 + case 'app.bsky.embed.video': 25 + return 'contains video'; 26 + case 'app.bsky.embed.recordWithMedia': 27 + return 'quotes post with media'; 28 + default: 29 + return 'contains unknown embed'; 30 + } 31 + }; 32 + </script> 33 + 34 + {#await post} 35 + loading post... 36 + {:then post} 37 + {#if post.ok} 38 + {@const record = post.value} 39 + {identifier} - [{record.embed ? getEmbedText(record.embed.$type) : null}] 40 + {record.text} 41 + {:else} 42 + error fetching post: {post.error} 43 + {/if} 44 + {/await}
+68
src/components/PostComposer.svelte
···
··· 1 + <script lang="ts"> 2 + import type { AtpClient } from '$lib/at/client'; 3 + import { ok, err, type Result } from '$lib/result'; 4 + import type { ComAtprotoRepoCreateRecord } from '@atcute/atproto'; 5 + import type { AppBskyFeedPost } from '@atcute/bluesky'; 6 + import type { InferOutput } from '@atcute/lexicons'; 7 + 8 + interface Props { 9 + client: AtpClient; 10 + } 11 + 12 + const { client }: Props = $props(); 13 + 14 + const post = async ( 15 + text: string 16 + ): Promise< 17 + Result<InferOutput<(typeof ComAtprotoRepoCreateRecord.mainSchema)['output']['schema']>, string> 18 + > => { 19 + const record: AppBskyFeedPost.Main = { 20 + $type: 'app.bsky.feed.post', 21 + text, 22 + createdAt: new Date().toISOString() 23 + }; 24 + 25 + const res = await client.atcute?.post('com.atproto.repo.createRecord', { 26 + input: { 27 + collection: 'app.bsky.feed.post', 28 + repo: client.didDoc!.did, 29 + record 30 + } 31 + }); 32 + 33 + if (!res) { 34 + return err('failed to post: not logged in'); 35 + } 36 + 37 + if (!res.ok) { 38 + return err(`failed to post: ${res.data.error}: ${res.data.message ?? 'no details'}`); 39 + } 40 + 41 + return ok(res.data); 42 + }; 43 + 44 + let postText = $state(''); 45 + let info = $state(''); 46 + </script> 47 + 48 + <div class="flex flex-col gap-0.5"> 49 + {#if info.length > 0} 50 + <span class="text-sm text-gray-500">{info}</span> 51 + {/if} 52 + <div class="flex gap-2"> 53 + <input bind:value={postText} type="text" placeholder="write your post here..." /> 54 + <button 55 + onclick={() => { 56 + post(postText).then((res) => { 57 + if (res.ok) { 58 + postText = ''; 59 + info = 'posted!'; 60 + setTimeout(() => (info = ''), 1000 * 3); 61 + } else { 62 + info = res.error; 63 + } 64 + }); 65 + }}>post</button 66 + > 67 + </div> 68 + </div>
+167
src/lib/at/client.ts
···
··· 1 + import { err, map, ok, type Result } from '$lib/result'; 2 + import { ComAtprotoIdentityResolveIdentity, ComAtprotoRepoGetRecord } from '@atcute/atproto'; 3 + import { Client as AtcuteClient, CredentialManager } from '@atcute/client'; 4 + import { safeParse, type Handle, type InferOutput } from '@atcute/lexicons'; 5 + import type { ActorIdentifier, AtprotoDid, Nsid, RecordKey } from '@atcute/lexicons/syntax'; 6 + import type { 7 + InferXRPCBodyOutput, 8 + ObjectSchema, 9 + RecordKeySchema, 10 + RecordSchema, 11 + XRPCQueryMetadata 12 + } from '@atcute/lexicons/validations'; 13 + import * as v from '@atcute/lexicons/validations'; 14 + import { LRUCache } from 'lru-cache'; 15 + 16 + export const MiniDocQuery = v.query('com.bad-example.identity.resolveMiniDoc', { 17 + params: v.object({ 18 + identifier: v.actorIdentifierString() 19 + }), 20 + output: { 21 + type: 'lex', 22 + schema: v.object({ 23 + did: v.didString(), 24 + handle: v.handleString(), 25 + pds: v.genericUriString(), 26 + signing_key: v.string() 27 + }) 28 + } 29 + }); 30 + export type MiniDoc = InferOutput<typeof MiniDocQuery.output.schema>; 31 + 32 + const cacheTtl = 1000 * 60 * 60 * 24; 33 + const handleCache = new LRUCache<Handle, AtprotoDid>({ 34 + max: 1000, 35 + ttl: cacheTtl 36 + }); 37 + const didDocCache = new LRUCache<ActorIdentifier, MiniDoc>({ 38 + max: 1000, 39 + ttl: cacheTtl 40 + }); 41 + const recordCache = new LRUCache< 42 + string, 43 + InferOutput<typeof ComAtprotoRepoGetRecord.mainSchema.output.schema> 44 + >({ 45 + max: 5000, 46 + ttl: cacheTtl 47 + }); 48 + 49 + export class AtpClient { 50 + public atcute: AtcuteClient | null = null; 51 + public didDoc: MiniDoc | null = null; 52 + 53 + private slingshotUrl: URL = new URL('https://slingshot.microcosm.blue'); 54 + private spacedustUrl: URL = new URL('https://spacedust.microcosm.blue'); 55 + 56 + async login(handle: Handle, password: string): Promise<Result<null, string>> { 57 + const didDoc = await this.resolveDidDoc(handle); 58 + if (!didDoc.ok) return err(didDoc.error); 59 + this.didDoc = didDoc.value; 60 + 61 + try { 62 + const handler = new CredentialManager({ service: didDoc.value.pds }); 63 + const rpc = new AtcuteClient({ handler }); 64 + await handler.login({ identifier: didDoc.value.did, password }); 65 + 66 + this.atcute = rpc; 67 + } catch (error) { 68 + return err(`failed to login: ${error}`); 69 + } 70 + 71 + return ok(null); 72 + } 73 + 74 + async getRecord< 75 + Collection extends Nsid, 76 + TObject extends ObjectSchema & { shape: { $type: v.LiteralSchema<Collection> } }, 77 + TKey extends RecordKeySchema, 78 + Schema extends RecordSchema<TObject, TKey>, 79 + Output extends InferOutput<Schema> 80 + >(schema: Schema, repo: ActorIdentifier, rkey: RecordKey): Promise<Result<Output, string>> { 81 + const collection = schema.object.shape.$type.expected; 82 + const cacheKey = `${repo}:${collection}:${rkey}`; 83 + 84 + const cached = recordCache.get(cacheKey); 85 + if (cached) return ok(cached.value as Output); 86 + 87 + const result = await fetchMicrocosm(this.slingshotUrl, ComAtprotoRepoGetRecord.mainSchema, { 88 + repo, 89 + collection, 90 + rkey 91 + }); 92 + 93 + if (!result.ok) return result; 94 + // console.info(`fetched record:`, result.value); 95 + 96 + const parsed = safeParse(schema, result.value.value); 97 + if (!parsed.ok) return err(parsed.message); 98 + 99 + recordCache.set(cacheKey, result.value); 100 + 101 + return ok(parsed.value as Output); 102 + } 103 + 104 + async resolveHandle(handle: Handle): Promise<Result<AtprotoDid, string>> { 105 + const cached = handleCache.get(handle); 106 + if (cached) return ok(cached); 107 + 108 + const res = await fetchMicrocosm( 109 + this.slingshotUrl, 110 + ComAtprotoIdentityResolveIdentity.mainSchema, 111 + { 112 + handle: handle 113 + } 114 + ); 115 + 116 + const mapped = map(res, (data) => data.did as AtprotoDid); 117 + 118 + if (mapped.ok) { 119 + handleCache.set(handle, mapped.value); 120 + } 121 + 122 + return mapped; 123 + } 124 + 125 + async resolveDidDoc(handleOrDid: ActorIdentifier): Promise<Result<MiniDoc, string>> { 126 + const cached = didDocCache.get(handleOrDid); 127 + if (cached) return ok(cached); 128 + 129 + const result = await fetchMicrocosm(this.slingshotUrl, MiniDocQuery, { 130 + identifier: handleOrDid 131 + }); 132 + 133 + if (result.ok) { 134 + didDocCache.set(handleOrDid, result.value); 135 + } 136 + 137 + return result; 138 + } 139 + } 140 + 141 + const fetchMicrocosm = async < 142 + Schema extends XRPCQueryMetadata, 143 + Output extends InferXRPCBodyOutput<Schema['output']> 144 + >( 145 + api: URL, 146 + schema: Schema, 147 + params?: URLSearchParams | Record<string, string>, 148 + init?: RequestInit 149 + ): Promise<Result<Output, string>> => { 150 + if (!schema.output || schema.output.type === 'blob') return err('schema must be blob'); 151 + if (params && !(params instanceof URLSearchParams)) params = new URLSearchParams(params); 152 + if (params?.size === 0) params = undefined; 153 + try { 154 + api.pathname = `/xrpc/${schema.nsid}`; 155 + api.search = params ? `?${params}` : ''; 156 + // console.info(`fetching:`, api.href); 157 + const response = await fetch(api, init); 158 + const body = await response.json(); 159 + if (response.status === 400) return err(`${body.error}: ${body.message}`); 160 + if (response.status !== 200) return err(`UnexpectedStatusCode: ${response.status}`); 161 + const parsed = safeParse(schema.output.schema, body); 162 + if (!parsed.ok) return err(parsed.message); 163 + return ok(parsed.value as Output); 164 + } catch (error) { 165 + return err(`FetchError: ${error}`); 166 + } 167 + };
src/lib/at/fetch.ts

This is a binary file and will not be displayed.

+3 -1
src/lib/index.ts
··· 1 - // place files you want to import through the `$lib` alias in this folder.
··· 1 + import { AtpClient } from './at/client'; 2 + 3 + export const client = new AtpClient();
+28
src/lib/result.ts
···
··· 1 + export type Result<T, E> = 2 + | { 3 + ok: true; 4 + value: T; 5 + } 6 + | { 7 + ok: false; 8 + error: E; 9 + }; 10 + 11 + export const ok = <T, E>(value: T): Result<T, E> => { 12 + return { ok: true, value }; 13 + }; 14 + export const err = <T, E>(error: E): Result<T, E> => { 15 + return { ok: false, error }; 16 + }; 17 + export const expect = <T, E>(v: Result<T, E>, msg: string = 'expected result to not be error:') => { 18 + if (v.ok) { 19 + return v.value; 20 + } 21 + throw `${msg} ${v.error}`; 22 + }; 23 + export const map = <T, E, U>(v: Result<T, E>, fn: (value: T) => U): Result<U, E> => { 24 + if (v.ok) { 25 + return ok(fn(v.value)); 26 + } 27 + return err(v.error); 28 + };
+11 -2
src/routes/+page.svelte
··· 1 - <h1>Welcome to SvelteKit</h1> 2 - <p>Visit <a href="https://svelte.dev/docs/kit">svelte.dev/docs/kit</a> to read the documentation</p>
··· 1 + <script lang="ts"> 2 + import BskyPost from '$components/BskyPost.svelte'; 3 + import PostComposer from '$components/PostComposer.svelte'; 4 + import { client } from '$lib'; 5 + </script> 6 + 7 + <div class="flex flex-col gap-4"> 8 + <PostComposer {client} /> 9 + <hr /> 10 + <BskyPost {client} identifier="nil.ptr.pet" rkey="3m3d5zguuxk2c" /> 11 + </div>
+14 -2
svelte.config.js
··· 5 const config = { 6 // Consult https://svelte.dev/docs/kit/integrations 7 // for more information about preprocessors 8 - preprocess: vitePreprocess(), 9 10 kit: { 11 // adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list. 12 // If your environment is not supported, or you settled on a specific environment, switch out the adapter. 13 // See https://svelte.dev/docs/kit/adapters for more information about adapters. 14 - adapter: adapter() 15 } 16 }; 17
··· 5 const config = { 6 // Consult https://svelte.dev/docs/kit/integrations 7 // for more information about preprocessors 8 + preprocess: [vitePreprocess()], 9 10 kit: { 11 // adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list. 12 // If your environment is not supported, or you settled on a specific environment, switch out the adapter. 13 // See https://svelte.dev/docs/kit/adapters for more information about adapters. 14 + adapter: adapter(), 15 + alias: { 16 + $lib: 'src/lib', 17 + '$lib/*': 'src/lib/*', 18 + $components: 'src/components', 19 + '$components/*': 'src/components/*' 20 + } 21 + }, 22 + 23 + compilerOptions: { 24 + experimental: { 25 + async: true 26 + } 27 } 28 }; 29
+8 -1
tsconfig.json
··· 9 "skipLibCheck": true, 10 "sourceMap": true, 11 "strict": true, 12 - "moduleResolution": "bundler" 13 } 14 // Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias 15 // except $lib which is handled by https://svelte.dev/docs/kit/configuration#files
··· 9 "skipLibCheck": true, 10 "sourceMap": true, 11 "strict": true, 12 + "moduleResolution": "bundler", 13 + "jsx": "react-jsx", 14 + "paths": { 15 + "$components": ["./src/components"], 16 + "$components/*": ["./src/components/*"], 17 + "$lib": ["./src/lib"], 18 + "$lib/*": ["./src/lib/*"] 19 + } 20 } 21 // Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias 22 // except $lib which is handled by https://svelte.dev/docs/kit/configuration#files