tracks lexicons and how many times they appeared on the jetstream

feat(client): show tracking since

ptr.pet d275783d 999365ad

verified
+23 -3
+13 -1
client/src/lib/api.ts
··· 1 1 import { dev } from "$app/environment"; 2 - import type { Events } from "./types"; 2 + import type { Events, Since } from "./types"; 3 3 import { PUBLIC_API_URL } from "$env/static/public"; 4 4 5 5 export const fetchEvents = async (): Promise<Events> => { ··· 13 13 const data = await response.json(); 14 14 return data; 15 15 }; 16 + 17 + export const fetchTrackingSince = async (): Promise<Since> => { 18 + const response = await fetch( 19 + `${dev ? "http" : "https"}://${PUBLIC_API_URL}/since`, 20 + ); 21 + if (!response.ok) { 22 + throw new Error(`(${response.status}): ${await response.json()}`); 23 + } 24 + 25 + const data = await response.json(); 26 + return data; 27 + };
+3
client/src/lib/types.ts
··· 13 13 count: number; 14 14 deleted_count: number; 15 15 }; 16 + export type Since = { 17 + since: number; 18 + }; 16 19 17 20 export type SortOption = "total" | "created" | "deleted" | "date";
+7 -2
client/src/routes/+page.svelte
··· 4 4 import { onMount, onDestroy } from "svelte"; 5 5 import { writable } from "svelte/store"; 6 6 import { PUBLIC_API_URL } from "$env/static/public"; 7 - import { fetchEvents } from "$lib/api"; 7 + import { fetchEvents, fetchTrackingSince } from "$lib/api"; 8 8 import { createRegexFilter } from "$lib/filter"; 9 9 import StatsCard from "$lib/components/StatsCard.svelte"; 10 10 import StatusBadge from "$lib/components/StatusBadge.svelte"; ··· 13 13 import SortControls from "$lib/components/SortControls.svelte"; 14 14 import BskyToggle from "$lib/components/BskyToggle.svelte"; 15 15 import RefreshControl from "$lib/components/RefreshControl.svelte"; 16 + import { formatTimestamp } from "$lib/format"; 16 17 17 18 const events = writable(new Map<string, EventRecord>()); 18 19 const pendingUpdates = new Map<string, EventRecord>(); ··· 28 29 .toArray(); 29 30 }); 30 31 let per_second = $state(0); 32 + let tracking_since = $state(0); 31 33 32 34 let all: EventRecord = $derived( 33 35 eventsList.reduce( ··· 118 120 } 119 121 return map; 120 122 }); 123 + tracking_since = (await fetchTrackingSince()).since; 121 124 } catch (err) { 122 125 error = 123 126 err instanceof Error ··· 225 228 > 226 229 <h1 class="text-4xl font-bold mr-4 text-gray-900">lexicon tracker</h1> 227 230 <p class="text-lg mt-1 text-gray-600"> 228 - tracks lexicons seen on the jetstream 231 + tracks lexicons seen on the jetstream {tracking_since === 0 232 + ? "" 233 + : `(since: ${formatTimestamp(tracking_since)})`} 229 234 </p> 230 235 </div> 231 236 </header>