perf upgrade
This commit is contained in:
@@ -4,7 +4,7 @@ import {
|
||||
MantineProvider as MantineProviderCore,
|
||||
} from "@mantine/core";
|
||||
import ColorSchemeProvider from "./color-scheme-provider";
|
||||
import { useState, useEffect } from "react";
|
||||
import { useState, useEffect, useMemo } from "react";
|
||||
|
||||
const commonInputStyles = {
|
||||
label: {
|
||||
@@ -60,10 +60,15 @@ const MantineProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
const colorScheme = isHydrated ? metadata.colorScheme || "auto" : "auto";
|
||||
const primaryColor = isHydrated ? metadata.accentColor || "blue" : "blue";
|
||||
|
||||
const themeWithPrimaryColor = useMemo(
|
||||
() => ({ ...theme, primaryColor }),
|
||||
[primaryColor]
|
||||
);
|
||||
|
||||
return (
|
||||
<MantineProviderCore
|
||||
defaultColorScheme={colorScheme}
|
||||
theme={{ ...theme, primaryColor }}
|
||||
theme={themeWithPrimaryColor}
|
||||
>
|
||||
<ColorSchemeProvider>{children}</ColorSchemeProvider>
|
||||
</MantineProviderCore>
|
||||
|
||||
@@ -35,12 +35,13 @@ export function createGroupsService(pb: PocketBase) {
|
||||
async deleteGroupsByTournament(tournamentId: string): Promise<void> {
|
||||
logger.info("PocketBase | Deleting all groups for tournament", { tournamentId });
|
||||
const groups = await pb.collection("groups").getFullList({
|
||||
filter: `tournament = "${tournamentId}"`
|
||||
filter: `tournament = "${tournamentId}"`,
|
||||
fields: "id",
|
||||
});
|
||||
|
||||
for (const group of groups) {
|
||||
await pb.collection("groups").delete(group.id);
|
||||
}
|
||||
await Promise.all(
|
||||
groups.map((group) => pb.collection("groups").delete(group.id))
|
||||
);
|
||||
},
|
||||
|
||||
async getGroup(groupId: string): Promise<Group> {
|
||||
|
||||
@@ -34,10 +34,19 @@ export function createTeamsService(pb: PocketBase) {
|
||||
logger.info("PocketBase | Creating team", data);
|
||||
|
||||
try {
|
||||
for (const playerId of data.players) {
|
||||
const playerExists = await pb.collection("players").getOne(playerId).catch(() => null);
|
||||
if (!playerExists) {
|
||||
throw new Error(`Player with ID ${playerId} not found`);
|
||||
if (data.players.length > 0) {
|
||||
const playerFilter = data.players
|
||||
.map((playerId) => `id = "${playerId}"`)
|
||||
.join(" || ");
|
||||
const existingPlayers = await pb.collection("players").getFullList({
|
||||
filter: playerFilter,
|
||||
fields: "id",
|
||||
});
|
||||
|
||||
if (existingPlayers.length !== data.players.length) {
|
||||
const foundIds = new Set(existingPlayers.map((player) => player.id));
|
||||
const missingId = data.players.find((playerId) => !foundIds.has(playerId));
|
||||
throw new Error(`Player with ID ${missingId} not found`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,11 +55,13 @@ export function createTeamsService(pb: PocketBase) {
|
||||
players: data.players
|
||||
});
|
||||
|
||||
for (const playerId of data.players) {
|
||||
await pb.collection("players").update(playerId, {
|
||||
"teams+": result.id
|
||||
});
|
||||
}
|
||||
await Promise.all(
|
||||
data.players.map((playerId) =>
|
||||
pb.collection("players").update(playerId, {
|
||||
"teams+": result.id
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
return transformTeam(await pb.collection("teams").getOne(result.id, {
|
||||
expand: "players, tournaments"
|
||||
@@ -72,10 +83,6 @@ export function createTeamsService(pb: PocketBase) {
|
||||
|
||||
const result = await pb.collection("teams").update(id, data);
|
||||
|
||||
if (data instanceof FormData && data.has('logo')) {
|
||||
await new Promise(resolve => setTimeout(resolve, 100));
|
||||
}
|
||||
|
||||
const updated = await pb.collection("teams").getOne(result.id, {
|
||||
expand: "players, tournaments",
|
||||
// @ts-ignore - Add cache busting
|
||||
|
||||
@@ -35,19 +35,22 @@ export function createTournamentsService(pb: PocketBase) {
|
||||
return transformTournament(tournamentResult, isAdmin);
|
||||
},
|
||||
async getMostRecentTournament(): Promise<Tournament> {
|
||||
const result = await pb
|
||||
const mostRecent = await pb
|
||||
.collection("tournaments")
|
||||
.getFirstListItem('',
|
||||
{
|
||||
expand: "teams, teams.players, matches, matches.tournament, matches.home, matches.away, matches.home.players, matches.away.players",
|
||||
sort: "-start_time",
|
||||
}
|
||||
);
|
||||
.getFirstListItem('', {
|
||||
fields: "id",
|
||||
sort: "-start_time",
|
||||
});
|
||||
|
||||
const teamStatsResult = await pb.collection("team_stats_per_tournament").getFullList({
|
||||
filter: `tournament_id = "${result.id}"`,
|
||||
sort: "-wins,-total_cups_made"
|
||||
});
|
||||
const [result, teamStatsResult] = await Promise.all([
|
||||
pb.collection("tournaments").getOne(mostRecent.id, {
|
||||
expand: "teams, teams.players, matches, matches.tournament, matches.home, matches.away, matches.home.players, matches.away.players",
|
||||
}),
|
||||
pb.collection("team_stats_per_tournament").getFullList({
|
||||
filter: `tournament_id = "${mostRecent.id}"`,
|
||||
sort: "-wins,-total_cups_made"
|
||||
}),
|
||||
]);
|
||||
|
||||
result.team_stats = teamStatsResult;
|
||||
|
||||
@@ -61,17 +64,33 @@ export function createTournamentsService(pb: PocketBase) {
|
||||
sort: "-start_time",
|
||||
});
|
||||
|
||||
const tournamentsWithStats = await Promise.all(result.map(async (tournament) => {
|
||||
const teamStats = await pb.collection("team_stats_per_tournament").getFullList({
|
||||
filter: `tournament_id = "${tournament.id}"`,
|
||||
let allTeamStats: any[] = [];
|
||||
if (result.length > 0) {
|
||||
const statsFilter = result
|
||||
.map((tournament) => `tournament_id = "${tournament.id}"`)
|
||||
.join(" || ");
|
||||
allTeamStats = await pb.collection("team_stats_per_tournament").getFullList({
|
||||
filter: statsFilter,
|
||||
sort: "-wins,-total_cups_made"
|
||||
});
|
||||
}
|
||||
|
||||
tournament.team_stats = teamStats;
|
||||
return tournament;
|
||||
}));
|
||||
const statsByTournament = new Map<string, any[]>();
|
||||
for (const stat of allTeamStats) {
|
||||
const key = stat.tournament_id as string;
|
||||
const group = statsByTournament.get(key);
|
||||
if (group) {
|
||||
group.push(stat);
|
||||
} else {
|
||||
statsByTournament.set(key, [stat]);
|
||||
}
|
||||
}
|
||||
|
||||
return tournamentsWithStats.map(transformTournamentInfo);
|
||||
for (const tournament of result) {
|
||||
tournament.team_stats = statsByTournament.get(tournament.id) ?? [];
|
||||
}
|
||||
|
||||
return result.map(transformTournamentInfo);
|
||||
},
|
||||
async createTournament(data: TournamentInput): Promise<Tournament> {
|
||||
const result = await pb
|
||||
|
||||
@@ -3,6 +3,22 @@ import { ensureSuperTokensBackend } from "../server";
|
||||
import { logger } from "../";
|
||||
import SuperTokens from "supertokens-node";
|
||||
|
||||
const USER_PHONE_TTL_MS = 60 * 1000;
|
||||
const userPhoneCache = new Map<string, { phone: string | undefined; expiresAt: number }>();
|
||||
|
||||
async function getUserPhone(userId: string): Promise<string | undefined> {
|
||||
const now = Date.now();
|
||||
const cached = userPhoneCache.get(userId);
|
||||
if (cached && cached.expiresAt > now) {
|
||||
return cached.phone;
|
||||
}
|
||||
|
||||
const user = await SuperTokens.getUser(userId);
|
||||
const phone = user?.phoneNumbers[0];
|
||||
userPhoneCache.set(userId, { phone, expiresAt: now + USER_PHONE_TTL_MS });
|
||||
return phone;
|
||||
}
|
||||
|
||||
export async function getSessionForStart(request: Request, options?: { sessionRequired?: boolean }) {
|
||||
ensureSuperTokensBackend();
|
||||
|
||||
@@ -52,15 +68,14 @@ export async function getSessionForStart(request: Request, options?: { sessionRe
|
||||
}
|
||||
}
|
||||
|
||||
const user = await SuperTokens.getUser(userId);
|
||||
|
||||
const phone = await getUserPhone(userId);
|
||||
|
||||
return {
|
||||
hasToken: true,
|
||||
accessTokenPayload: session.accessTokenPayload,
|
||||
userId,
|
||||
sessionHandle: session.accessTokenPayload?.sessionHandle,
|
||||
phone: user?.phoneNumbers[0]
|
||||
phone
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { logger } from "../../logger";
|
||||
import { ErrorType, ServerError, ServerResult } from "../types";
|
||||
import { pbAdmin } from "../../pocketbase/client";
|
||||
import { getRequest } from "@tanstack/react-start/server";
|
||||
import { isRedirect } from "@tanstack/react-router";
|
||||
|
||||
@@ -51,21 +50,22 @@ export const toServerResult = async <T>(
|
||||
fnName = serverFn.name || 'unknown';
|
||||
}
|
||||
|
||||
try {
|
||||
await pbAdmin.authPromise;
|
||||
await pbAdmin.createActivity({
|
||||
name: fnName,
|
||||
duration,
|
||||
success: false,
|
||||
error: mappedError.message,
|
||||
arguments: {
|
||||
errorType: mappedError.code,
|
||||
statusCode: mappedError.statusCode,
|
||||
userMessage: mappedError.userMessage,
|
||||
},
|
||||
});
|
||||
} catch (activityError) {
|
||||
}
|
||||
import("../../pocketbase/client")
|
||||
.then(async ({ pbAdmin }) => {
|
||||
await pbAdmin.authPromise;
|
||||
await pbAdmin.createActivity({
|
||||
name: fnName,
|
||||
duration,
|
||||
success: false,
|
||||
error: mappedError.message,
|
||||
arguments: {
|
||||
errorType: mappedError.code,
|
||||
statusCode: mappedError.statusCode,
|
||||
userMessage: mappedError.userMessage,
|
||||
},
|
||||
});
|
||||
})
|
||||
.catch(() => {});
|
||||
|
||||
return { success: false, error: mappedError };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user