sendou.ink/app/features/sendouq-streams/core/streams.server.ts
Kalle dd1adad94b
Some checks are pending
Tests and checks on push / run-checks-and-tests (push) Waiting to run
Updates translation progress / update-translation-progress-issue (push) Waiting to run
BIome v2 upgrade
2025-06-22 16:49:27 +03:00

104 lines
2.7 KiB
TypeScript

import cachified from "@epic-web/cachified";
import {
cachedFullUserLeaderboard,
type UserLeaderboardWithAdditionsItem,
} from "~/features/leaderboards/core/leaderboards.server";
import * as Seasons from "~/features/mmr/core/Seasons";
import { TIERS } from "~/features/mmr/mmr-constants";
import * as QStreamsRepository from "~/features/sendouq-streams/QStreamsRepository.server";
import { getStreams } from "~/modules/twitch";
import type { MappedStream } from "~/modules/twitch/streams";
import { cache, IN_MILLISECONDS, ttl } from "~/utils/cache.server";
import { logger } from "~/utils/logger";
import { SENDOUQ_STREAMS_KEY } from "../q-streams-constants";
export function cachedStreams() {
const season = Seasons.currentOrPrevious()!;
return cachified({
key: SENDOUQ_STREAMS_KEY,
cache: cache,
ttl: ttl(IN_MILLISECONDS.HALF_HOUR),
async getFreshValue() {
return streamedMatches({
matchPlayers: await QStreamsRepository.activeMatchPlayers(),
streams: await getStreams(),
leaderboard: await cachedFullUserLeaderboard(season.nth),
}).sort((a, b) => {
const aTierIndex = TIERS.findIndex(
(tier) => tier.name === a.tier?.name,
);
const bTierIndex = TIERS.findIndex(
(tier) => tier.name === b.tier?.name,
);
// missing tiers sorted last
if (aTierIndex === -1 && bTierIndex !== -1) {
return 1;
}
if (aTierIndex !== -1 && bTierIndex === -1) {
return -1;
}
// sort by base tier
if (aTierIndex !== bTierIndex) {
return aTierIndex - bTierIndex;
}
// if base tier is the same, sort by plus
if (a.tier?.isPlus !== b.tier?.isPlus) {
return a.tier?.isPlus ? -1 : 1;
}
// if tier is the same, sort by viewer count
return b.stream.viewerCount - a.stream.viewerCount;
});
},
});
}
export function refreshStreamsCache() {
cache.delete(SENDOUQ_STREAMS_KEY);
void cachedStreams().catch((err) =>
logger.error(`Failed to refresh cache: ${err}`),
);
}
function streamedMatches({
matchPlayers,
streams,
leaderboard,
}: {
matchPlayers: QStreamsRepository.ActiveMatchPlayersItem[];
streams: MappedStream[];
leaderboard: UserLeaderboardWithAdditionsItem[];
}) {
return matchPlayers.flatMap((player) => {
const stream = streams.find(
(stream) => stream.twitchUserName === player.user?.twitch?.toLowerCase(),
);
if (!stream) {
return [];
}
const leaderboardEntry = leaderboard.find(
(entry) => entry.id === player.user?.id,
);
return {
stream,
match: {
id: player.groupMatchId,
createdAt: player.groupMatchCreatedAt,
},
user: {
...player.user!,
twitch: player.user!.twitch!,
},
weaponSplId: leaderboardEntry?.weaponSplId,
tier: leaderboardEntry?.tier,
};
});
}