tracks lexicons and how many times they appeared on the jetstream

feat(client): load data in server function so we dont have weird empty gap with no data

ptr.pet 48d94e68 452aff95

verified
Changed files
+40 -30
.tangled
workflows
client
-3
.tangled/workflows/build.yml
···
- gnused
steps:
-
- name: test server
-
command: |
-
cd server && cargo test
- name: build client
command: |
export PUBLIC_API_URL="localhost:3713"
···
- gnused
steps:
- name: build client
command: |
export PUBLIC_API_URL="localhost:3713"
+3 -2
client/src/routes/+layout.ts
···
-
export const prerender = true;
-
export const ssr = false;
···
+
export const prerender = false;
+
export const ssr = true;
+
export const csr = true;
+7
client/src/routes/+page.server.ts
···
···
+
import { fetchEvents, fetchTrackingSince } from "$lib/api";
+
+
export const load = async () => {
+
const events = await fetchEvents();
+
const trackingSince = await fetchTrackingSince();
+
return { events, trackingSince };
+
};
+30 -25
client/src/routes/+page.svelte
···
<script lang="ts">
import { dev } from "$app/environment";
-
import type { EventRecord, NsidCount, SortOption } from "$lib/types";
import { onMount, onDestroy } from "svelte";
import { writable } from "svelte/store";
import { PUBLIC_API_URL } from "$env/static/public";
···
import RefreshControl from "$lib/components/RefreshControl.svelte";
import { formatTimestamp } from "$lib/format";
-
const events = writable(new Map<string, EventRecord>());
const pendingUpdates = new Map<string, EventRecord>();
let eventsList: NsidCount[] = $state([]);
let updateTimer: NodeJS.Timeout | null = null;
···
}))
.toArray();
});
-
let per_second = $state(0);
-
let tracking_since = $state(0);
let all: EventRecord = $derived(
eventsList.reduce(
···
};
websocket.onmessage = async (event) => {
const jsonData = JSON.parse(event.data);
-
-
if (jsonData.per_second > 0) {
-
per_second = jsonData.per_second;
-
}
-
-
// Store updates in pending map if refresh rate is set
if (refreshRate) {
for (const [nsid, event] of Object.entries(jsonData.events)) {
pendingUpdates.set(nsid, event as EventRecord);
}
} else {
-
// Apply updates immediately if no refresh rate
-
events.update((map) => {
-
for (const [nsid, event] of Object.entries(
-
jsonData.events,
-
)) {
-
map.set(nsid, event as EventRecord);
-
}
-
return map;
-
});
}
};
websocket.onerror = (error) => {
···
error = null;
const data = await fetchEvents();
per_second = data.per_second;
-
events.update((map) => {
-
for (const [nsid, event] of Object.entries(data.events)) {
-
map.set(nsid, event);
-
}
-
return map;
-
});
tracking_since = (await fetchTrackingSince()).since;
} catch (err) {
error =
···
<script lang="ts">
import { dev } from "$app/environment";
+
import type {
+
EventRecord,
+
Events,
+
NsidCount,
+
Since,
+
SortOption,
+
} from "$lib/types";
import { onMount, onDestroy } from "svelte";
import { writable } from "svelte/store";
import { PUBLIC_API_URL } from "$env/static/public";
···
import RefreshControl from "$lib/components/RefreshControl.svelte";
import { formatTimestamp } from "$lib/format";
+
type Props = {
+
data: { events: Events; trackingSince: Since };
+
};
+
+
const { data }: Props = $props();
+
+
const events = writable(
+
new Map<string, EventRecord>(Object.entries(data.events.events)),
+
);
const pendingUpdates = new Map<string, EventRecord>();
let eventsList: NsidCount[] = $state([]);
let updateTimer: NodeJS.Timeout | null = null;
···
}))
.toArray();
});
+
let per_second = $state(data.events.per_second);
+
let tracking_since = $state(data.trackingSince.since);
+
+
const applyEvents = (newEvents: Record<string, EventRecord>) => {
+
events.update((map) => {
+
for (const [nsid, event] of Object.entries(newEvents)) {
+
map.set(nsid, event);
+
}
+
return map;
+
});
+
};
let all: EventRecord = $derived(
eventsList.reduce(
···
};
websocket.onmessage = async (event) => {
const jsonData = JSON.parse(event.data);
+
per_second = jsonData.per_second;
if (refreshRate) {
for (const [nsid, event] of Object.entries(jsonData.events)) {
pendingUpdates.set(nsid, event as EventRecord);
}
} else {
+
applyEvents(jsonData.events);
}
};
websocket.onerror = (error) => {
···
error = null;
const data = await fetchEvents();
per_second = data.per_second;
+
applyEvents(data.events);
tracking_since = (await fetchTrackingSince()).since;
} catch (err) {
error =