Reuse collator and precompute fleet sort keys

This commit is contained in:
2026-10-05 15:39:12 -04:00
parent d24c52b5cc
commit ad0a0e1033
+22 -12
View File
@@ -1,3 +1,7 @@
<script module lang="ts">
const serverTitleCollator = new Intl.Collator(undefined, { numeric: true });
</script>
<script lang="ts"> <script lang="ts">
let { data }: { data: import('./$types').PageData } = $props(); let { data }: { data: import('./$types').PageData } = $props();
const snapshot = $derived($fleet.receivedAt ? $fleet : data.fleetSnapshot); const snapshot = $derived($fleet.receivedAt ? $fleet : data.fleetSnapshot);
@@ -92,15 +96,21 @@
let problems = $derived(servers.filter(server => server.health === 'offline' || server.health === 'stale')); let problems = $derived(servers.filter(server => server.health === 'offline' || server.health === 'stale'));
let starting = $derived(servers.filter(server => server.health === 'starting').length); let starting = $derived(servers.filter(server => server.health === 'starting').length);
let provisioning = $derived(servers.filter(server => server.health === 'provisioning').length); let provisioning = $derived(servers.filter(server => server.health === 'provisioning').length);
let filtered = $derived(servers.filter(server => matchesFleet(server, query, filter, game, pinned, activeOperations, observationNow())) let filtered = $derived.by(() => {
.sort((a, b) => { const now = observationNow();
const pinOrder = Number(pinned.includes(b.name)) - Number(pinned.includes(a.name)); const pinnedNames = new Set(pinned);
if (pinOrder) return pinOrder; return servers.filter(server => matchesFleet(server, query, filter, game, pinned, activeOperations, now))
const rank = (server: FleetServer) => sort === 'players' ? (freshServer(server, observationNow()) ? server.last_players ?? -1 : -1) .map(server => ({
: sort === 'round' ? currentRound(server, $telemetryByServer.get(server.name), observationNow()) ?? -1 server,
: sort === 'duration' ? matchDuration(server) : 0; title: serverTitle(server.name),
return rank(b) - rank(a) || serverTitle(a.name).localeCompare(serverTitle(b.name), undefined, { numeric: true }); pinned: Number(pinnedNames.has(server.name)),
})); rank: sort === 'players' ? (freshServer(server, now) ? server.last_players ?? -1 : -1)
: sort === 'round' ? currentRound(server, $telemetryByServer.get(server.name), now) ?? -1
: sort === 'duration' ? matchDuration(server, now) : 0
}))
.sort((a, b) => b.pinned - a.pinned || b.rank - a.rank || serverTitleCollator.compare(a.title, b.title))
.map(({ server }) => server);
});
let groups = $derived.by(() => { let groups = $derived.by(() => {
const result = new Map<string, { title: string; game: string; servers: FleetServer[]; launch: ReturnType<typeof fleetIdentity>['launch'] }>(); const result = new Map<string, { title: string; game: string; servers: FleetServer[]; launch: ReturnType<typeof fleetIdentity>['launch'] }>();
for (const server of filtered) { for (const server of filtered) {
@@ -116,9 +126,9 @@
let spotlight = $derived(servers.filter(server => currentRound(server, $telemetryByServer.get(server.name), observationNow()) !== null) let spotlight = $derived(servers.filter(server => currentRound(server, $telemetryByServer.get(server.name), observationNow()) !== null)
.sort((a, b) => matchDuration(b) - matchDuration(a))[0]); .sort((a, b) => matchDuration(b) - matchDuration(a))[0]);
function matchDuration(server: FleetServer): number { function matchDuration(server: FleetServer, now = observationNow()): number {
return freshServer(server, observationNow()) && server.active_since && server.game_started_at && !server.game_ended_at return freshServer(server, now) && server.active_since && server.game_started_at && !server.game_ended_at
&& (server.last_players ?? 0) > 0 ? Math.max(0, observationNow() - Date.parse(server.game_started_at)) : -1; && (server.last_players ?? 0) > 0 ? Math.max(0, now - Date.parse(server.game_started_at)) : -1;
} }
function togglePin(name: string) { pinned = pinned.includes(name) ? pinned.filter(item => item !== name) : [...pinned, name]; } function togglePin(name: string) { pinned = pinned.includes(name) ? pinned.filter(item => item !== name) : [...pinned, name]; }
function launch(selection: { game: ZombieGame; slug: string } | null = null) { function launch(selection: { game: ZombieGame; slug: string } | null = null) {