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: count all nsids as a separate entry in nsid_counts so that we dont have to run COUNT

dusk 2b6570e6 c2260e20

+37 -30
+8 -9
src/lib/db.ts
··· 7 7 deleted_count: number; 8 8 } 9 9 10 + const ALL_NSID = "*"; 11 + 10 12 class EventTracker { 11 13 private db: Database; 12 14 private insertNsidQuery; 13 15 private insertEventQuery; 14 16 private updateCountQuery; 15 17 private getNsidCountQuery; 16 - private getEventCountQuery; 17 18 18 19 constructor() { 19 20 this.db = new Database("events.sqlite"); ··· 77 78 FROM nsid_counts 78 79 ORDER BY count DESC 79 80 `); 80 - this.getEventCountQuery = this.db.query( 81 - `SELECT COUNT(*) as count FROM events`, 82 - ); 81 + this.insertNsidQuery.run(ALL_NSID); 83 82 } 84 83 85 84 addEvent = (nsid: string, timestamp: number, deleted: boolean) => { ··· 91 90 $deleted: deleted, 92 91 $timestamp: timestamp, 93 92 }); 93 + this.updateCountQuery.run({ 94 + $nsid: ALL_NSID, 95 + $deleted: deleted, 96 + $timestamp: timestamp, 97 + }); 94 98 }); 95 99 96 100 tx(); ··· 98 102 99 103 getNsidCounts = (): EventRecord[] => { 100 104 return this.getNsidCountQuery.all() as EventRecord[]; 101 - }; 102 - 103 - getEventCount = (): number => { 104 - const result = this.getEventCountQuery.get() as { count: number }; 105 - return result.count; 106 105 }; 107 106 108 107 close = () => {
-2
src/routes/+page.server.ts
··· 2 2 3 3 export const load = async () => { 4 4 const events = eventTracker.getNsidCounts(); 5 - const totalEvents = eventTracker.getEventCount(); 6 5 7 6 return { 8 7 events, 9 - totalEvents, 10 8 }; 11 9 };
+28 -14
src/routes/+page.svelte
··· 8 8 let { data }: Props = $props(); 9 9 10 10 let events: EventRecord[] = $state(data.events); 11 - let totalEvents = $state(data.totalEvents); 11 + let usableEvents = $derived(events.filter((e) => e.nsid !== "*")); 12 + let allNsidRecord = $derived( 13 + events.find((e) => { 14 + return e.nsid === "*"; 15 + }), 16 + ); 12 17 let error: string | null = $state(null); 13 18 let dontShowBsky = $state(false); 14 19 ··· 23 28 24 29 const data = await response.json(); 25 30 events = data.events; 26 - totalEvents = data.totalEvents; 27 31 } catch (err) { 28 32 error = 29 33 err instanceof Error ··· 57 61 </p> 58 62 </header> 59 63 60 - <div class="mx-auto w-fit grid grid-cols-1 md:grid-cols-2 mb-8"> 64 + <div class="mx-auto w-fit grid grid-cols-2 md:grid-cols-3 mb-8"> 61 65 <div 62 66 class="bg-gradient-to-r from-blue-50 to-blue-100 p-3 md:p-6 rounded-lg border border-blue-200" 63 67 > 64 68 <h3 class="text-base font-medium text-blue-700 mb-2"> 65 - total events 69 + total events created 66 70 </h3> 67 71 <p class="text-3xl font-bold text-blue-900"> 68 - {formatNumber(totalEvents)} 72 + {// eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain 73 + formatNumber(allNsidRecord?.count!)} 69 74 </p> 70 75 </div> 71 76 <div 72 - class="bg-gradient-to-r from-green-50 to-green-100 p-3 md:p-6 rounded-lg border border-green-200" 77 + class="bg-gradient-to-r from-red-50 to-red-100 p-3 md:p-6 rounded-lg border border-red-200" 73 78 > 74 - <h3 class="text-base font-medium text-green-700 mb-2"> 79 + <h3 class="text-base font-medium text-red-700 mb-2"> 80 + total events deleted 81 + </h3> 82 + <p class="text-3xl font-bold text-red-900"> 83 + {// eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain 84 + formatNumber(allNsidRecord?.deleted_count!)} 85 + </p> 86 + </div> 87 + <div 88 + class="bg-gradient-to-r from-orange-50 to-orange-100 p-3 md:p-6 rounded-lg border border-orange-200" 89 + > 90 + <h3 class="text-base font-medium text-orange-700 mb-2"> 75 91 unique collections 76 92 </h3> 77 - <p class="text-3xl font-bold text-green-900"> 78 - {formatNumber(events.length)} 93 + <p class="text-3xl font-bold text-orange-900"> 94 + {formatNumber(usableEvents.length)} 79 95 </p> 80 96 </div> 81 97 </div> ··· 101 117 </div> 102 118 {/if} 103 119 104 - {#if events.length > 0} 120 + {#if usableEvents.length > 0} 105 121 <div class="mb-8"> 106 122 <h2 class="text-2xl font-bold mb-6 text-gray-900"> 107 123 events by collection 108 124 </h2> 109 - <div 110 - class="grid md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4" 111 - > 112 - {#each events.filter((e) => { 125 + <div class="grid grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4"> 126 + {#each usableEvents.filter((e) => { 113 127 return dontShowBsky ? !e.nsid.startsWith("app.bsky.") : true; 114 128 }) as event, index (event.nsid)} 115 129 <div
+1 -5
src/routes/api/events/+server.ts
··· 4 4 export const GET = async () => { 5 5 try { 6 6 const events = eventTracker.getNsidCounts(); 7 - const totalEvents = eventTracker.getEventCount(); 8 7 9 - return json({ 10 - events, 11 - totalEvents, 12 - }); 8 + return json({ events }); 13 9 } catch (error) { 14 10 console.error("error fetching events:", error); 15 11 return json({ error: "failed to fetch events" }, { status: 500 });