tracks lexicons and how many times they appeared on the jetstream
3
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat(client): make stat cards numbers animated, rename text

dusk f065b614 a13ddcde

+23 -14
+7
client/bun.lock
··· 3 3 "workspaces": { 4 4 "": { 5 5 "name": "nsid-tracker", 6 + "dependencies": { 7 + "@number-flow/svelte": "^0.3.9", 8 + }, 6 9 "devDependencies": { 7 10 "@eslint/compat": "^1.2.5", 8 11 "@eslint/js": "^9.18.0", ··· 121 124 "@nodelib/fs.stat": ["@nodelib/fs.stat@2.0.5", "", {}, "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="], 122 125 123 126 "@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="], 127 + 128 + "@number-flow/svelte": ["@number-flow/svelte@0.3.9", "", { "dependencies": { "esm-env": "^1.1.4", "number-flow": "0.5.8" }, "peerDependencies": { "svelte": "^4 || ^5" } }, "sha512-CTw1+e0074GzbPX2IHcNCaK8nqxGNCOIUnQUjEjhcmBwBxOAhN3GYLQ6cJHvhQnWwplVe4eQ3z+c25Vttr2stQ=="], 124 129 125 130 "@polka/url": ["@polka/url@1.0.0-next.29", "", {}, "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww=="], 126 131 ··· 441 446 "nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], 442 447 443 448 "natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="], 449 + 450 + "number-flow": ["number-flow@0.5.8", "", { "dependencies": { "esm-env": "^1.1.4" } }, "sha512-FPr1DumWyGi5Nucoug14bC6xEz70A1TnhgSHhKyfqjgji2SOTz+iLJxKtv37N5JyJbteGYCm6NQ9p1O4KZ7iiA=="], 444 451 445 452 "optionator": ["optionator@0.9.4", "", { "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", "word-wrap": "^1.2.5" } }, "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g=="], 446 453
+4 -1
client/package.json
··· 29 29 "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", 30 30 "lint": "eslint ." 31 31 }, 32 - "type": "module" 32 + "type": "module", 33 + "dependencies": { 34 + "@number-flow/svelte": "^0.3.9" 35 + } 33 36 }
+3 -2
client/src/lib/components/StatsCard.svelte
··· 1 1 <script lang="ts"> 2 2 import { formatNumber } from "$lib/format"; 3 + import NumberFlow from "@number-flow/svelte"; 3 4 4 5 const colorClasses = { 5 6 green: { ··· 40 41 </script> 41 42 42 43 <div 43 - class="min-w-fit bg-gradient-to-r {colors.bg} p-3 md:p-6 rounded-lg border {colors.border}" 44 + class="bg-gradient-to-r {colors.bg} p-3 md:p-6 rounded-lg border {colors.border}" 44 45 > 45 46 <h3 class="text-base font-medium {colors.titleText} mb-2"> 46 47 {title} 47 48 </h3> 48 49 <p class="text-xl md:text-3xl font-bold {colors.valueText}"> 49 - {formatNumber(value)} 50 + <NumberFlow {value} /> 50 51 </p> 51 52 </div>
+9 -11
client/src/routes/+page.svelte
··· 142 142 </script> 143 143 144 144 <svelte:head> 145 - <title>bluesky jetstream tracker</title> 145 + <title>lexicon tracker</title> 146 146 <meta 147 147 name="description" 148 148 content="tracks bluesky jetstream events by collection" ··· 151 151 152 152 <div class="md:max-w-[61vw] mx-auto p-2"> 153 153 <header class="text-center mb-8"> 154 - <h1 class="text-4xl font-bold mb-2 text-gray-900"> 155 - bluesky event tracker 156 - </h1> 157 - <p class="text-gray-600"> 158 - tracking of bluesky events by collection from the jetstream 154 + <h1 class="text-4xl font-bold mb-2 text-gray-900">lexicon tracker</h1> 155 + <p class="text-lg text-gray-600"> 156 + tracks lexicons seen on the jetstream 159 157 </p> 160 158 </header> 161 159 162 - <div class="min-w-fit grid grid-cols-2 xl:grid-cols-4 gap-2 2xl:gap-6 mb-8"> 160 + <div 161 + class="min-w-fit grid grid-cols-2 xl:grid-cols-4 gap-2 2xl:gap-6 2xl:mx-16 mb-8" 162 + > 163 163 <StatsCard 164 164 title="total creation" 165 165 value={all.count} ··· 193 193 {#if eventsList.length > 0} 194 194 <div class="mb-8"> 195 195 <div class="flex flex-wrap items-center gap-3 mb-3"> 196 - <h2 class="text-2xl font-bold text-gray-900"> 197 - events by collection 198 - </h2> 196 + <h2 class="text-2xl font-bold text-gray-900">seen lexicons</h2> 199 197 <StatusBadge status={websocketStatus} /> 200 198 </div> 201 199 <FilterControls ··· 215 213 {:else} 216 214 <div class="text-center py-12 bg-gray-50 rounded-lg"> 217 215 <div class="text-gray-400 text-4xl mb-4">📊</div> 218 - <p class="text-gray-600">no events tracked yet.</p> 216 + <p class="text-gray-600">no events tracked yet. try refreshing?</p> 219 217 </div> 220 218 {/if} 221 219 </div>