API optimisations (#343)

* feat: api optimisation

* feat: emulator rename
This commit is contained in:
DecDuck
2026-02-06 23:12:03 +11:00
committed by GitHub
parent d6920700cb
commit bc5623cc78
20 changed files with 246 additions and 134 deletions
@@ -20,7 +20,7 @@ export type AdminFetchGameType = Prisma.GameGetPayload<{
setups: true;
launches: {
include: {
executor: {
emulator: {
include: {
gameVersion: {
select: {
@@ -38,7 +38,7 @@ export type AdminFetchGameType = Prisma.GameGetPayload<{
};
};
};
executions: {
emulations: {
select: {
launchId: true;
};
@@ -77,7 +77,7 @@ export default defineEventHandler<
setups: true,
launches: {
include: {
executor: {
emulator: {
include: {
gameVersion: {
select: {
@@ -95,7 +95,7 @@ export default defineEventHandler<
},
},
},
executions: {
emulations: {
select: {
launchId: true,
},
@@ -19,7 +19,7 @@ export const ImportVersion = type({
name: "string",
launch: "string",
umuId: "string?",
executorId: "string?",
emulatorId: "string?",
suggestions: "string[]?",
}).array(),
@@ -17,7 +17,7 @@ export default defineClientEventHandler(async (h3) => {
include: {
launches: {
include: {
executor: {
emulator: {
include: {
gameVersion: {
select: {
@@ -46,11 +46,11 @@ export default defineClientEventHandler(async (h3) => {
...gameVersion,
launches: gameVersion.launches.map((launch) => ({
...launch,
executor: launch.executor
emulator: launch.emulator
? {
...launch.executor,
...launch.emulator,
gameVersion: undefined,
gameId: launch.executor.gameVersion.game.id,
gameId: launch.emulator.gameVersion.game.id,
}
: undefined,
})),
@@ -5,6 +5,7 @@ import type { GameVersionSize } from "~/server/internal/gamesize";
import gameSizeManager from "~/server/internal/gamesize";
type VersionDownloadOption = {
gameId: string;
versionId: string;
displayName?: string | undefined;
versionPath?: string | undefined;
@@ -43,7 +44,7 @@ export default defineClientEventHandler(async (h3) => {
launches: {
select: {
platform: true,
executor: {
emulator: {
select: {
gameVersion: {
select: {
@@ -78,18 +79,16 @@ export default defineClientEventHandler(async (h3) => {
if (!platformOptions.has(launch.platform))
platformOptions.set(launch.platform, []);
if ("executor" in launch && launch.executor) {
if ("emulator" in launch && launch.emulator) {
const old = platformOptions.get(launch.platform)!;
const gv = launch.emulator.gameVersion;
old.push({
gameId: launch.executor.gameVersion.game.id,
versionId: launch.executor.gameVersion.versionId,
name: launch.executor.gameVersion.game.mName,
iconObjectId: launch.executor.gameVersion.game.mIconObjectId,
shortDescription:
launch.executor.gameVersion.game.mShortDescription,
size: (await gameSizeManager.getVersionSize(
launch.executor.gameVersion.versionId,
))!,
gameId: gv.game.id,
versionId: gv.versionId,
name: gv.game.mName,
iconObjectId: gv.game.mIconObjectId,
shortDescription: gv.game.mShortDescription,
size: (await gameSizeManager.getVersionSize(gv.versionId))!,
});
}
}
@@ -101,6 +100,7 @@ export default defineClientEventHandler(async (h3) => {
.map(
([platform, requiredContent]) =>
({
gameId: v.gameId,
versionId: v.versionId,
displayName: v.displayName || undefined,
versionPath: v.versionPath || undefined,
+31 -2
View File
@@ -21,6 +21,12 @@ export default defineEventHandler(async (h3) => {
launches: true,
setups: true,
},
omit: {
dropletManifest: true,
},
orderBy: {
versionIndex: "desc",
},
},
publishers: {
select: {
@@ -57,7 +63,30 @@ export default defineEventHandler(async (h3) => {
},
});
const size = (await gameSizeManager.getGameBreakdown(gameId))!;
const sizes = await Promise.all(
game.versions!.map(
async (v) => (await gameSizeManager.getVersionSize(v.versionId))!,
),
);
return { game, rating, size };
const platforms = new Set(
game
.versions!.map((v) => [
...v.setups.map((v) => v.platform),
...v.launches.map((v) => v.platform),
])
.flat(),
);
const gameV: Omit<typeof game, "versions"> = game;
// @ts-expect-error value exists at runtime
delete gameV.versions;
return {
game: gameV,
rating,
sizes,
platforms: platforms.values().toArray(),
};
});
+29 -27
View File
@@ -19,6 +19,7 @@ import gameSizeManager from "~/server/internal/gamesize";
import type { ImportVersion } from "~/server/api/v1/admin/import/version/index.post";
import { GameType, type Platform } from "~/prisma/client/enums";
import { castManifest } from "./manifest/utils";
import { Shescape } from "shescape";
export function createGameImportTaskId(libraryId: string, libraryPath: string) {
return createHash("md5")
@@ -35,9 +36,9 @@ export function createVersionImportTaskKey(
.digest("hex");
}
export interface ExecutorVersionGuess {
type: "executor";
executorId: string;
export interface EmulatorVersionGuess {
type: "emulator";
emulatorId: string;
icon: string;
gameName: string;
versionName: string;
@@ -51,7 +52,7 @@ export interface PlatformVersionGuess {
export type VersionGuess = {
filename: string;
match: number;
} & (PlatformVersionGuess | ExecutorVersionGuess);
} & (PlatformVersionGuess | EmulatorVersionGuess);
export interface UnimportedVersionInformation {
type: "local" | "depot";
@@ -61,6 +62,7 @@ export interface UnimportedVersionInformation {
class LibraryManager {
private libraries: Map<string, LibraryProvider<unknown>> = new Map();
private shescape = new Shescape({});
addLibrary(library: LibraryProvider<unknown>) {
this.libraries.set(library.id(), library);
@@ -253,19 +255,19 @@ class LibraryManager {
],
};
const executorSuggestions = await prisma.launchConfiguration.findMany({
const emulators = await prisma.launchConfiguration.findMany({
where: {
executorSuggestions: {
emulatorSuggestions: {
isEmpty: false,
},
gameVersion: {
game: {
type: GameType.Executor,
type: GameType.Emulator,
},
},
},
select: {
executorSuggestions: true,
emulatorSuggestions: true,
gameVersion: {
select: {
game: {
@@ -318,28 +320,28 @@ class LibraryManager {
const fuzzyValue = fuzzy(basename, game.mName);
options.push({
type: "platform",
filename: filename.replaceAll(" ", "\\ "),
filename: this.shescape.escape(filename),
platform: platform as Platform,
match: fuzzyValue,
});
}
}
for (const executorSuggestion of executorSuggestions) {
for (const suggestion of executorSuggestion.executorSuggestions) {
for (const emulator of emulators) {
for (const suggestion of emulator.emulatorSuggestions) {
if (suggestion != ext) continue;
const fuzzyValue = fuzzy(basename, game.mName);
options.push({
type: "executor",
filename: filename.replaceAll(" ", "\\ "),
type: "emulator",
filename: this.shescape.escape(filename),
match: fuzzyValue,
executorId: executorSuggestion.launchId,
emulatorId: emulator.launchId,
icon: executorSuggestion.gameVersion.game.mIconObjectId,
gameName: executorSuggestion.gameVersion.game.mName,
versionName: (executorSuggestion.gameVersion.displayName ??
executorSuggestion.gameVersion.versionPath)!,
launchName: executorSuggestion.name,
platform: executorSuggestion.platform,
icon: emulator.gameVersion.game.mIconObjectId,
gameName: emulator.gameVersion.game.mName,
versionName: (emulator.gameVersion.displayName ??
emulator.gameVersion.versionPath)!,
launchName: emulator.name,
platform: emulator.platform,
});
}
}
@@ -382,10 +384,10 @@ class LibraryManager {
});
if (!game || !game.libraryId) return undefined;
if (game.type === GameType.Redist && !metadata.onlySetup)
if (game.type === GameType.Dependency && !metadata.onlySetup)
throw createError({
statusCode: 400,
message: "Redistributables can only be in setup-only mode.",
message: "Dependencies can only be in setup-only mode.",
});
const library = this.libraries.get(game.libraryId);
@@ -474,13 +476,13 @@ class LibraryManager {
name: v.name,
command: v.launch,
platform: v.platform,
...(v.executorId && game.type === "Game"
...(v.emulatorId && game.type === "Game"
? {
executorId: v.executorId,
emulatorId: v.emulatorId,
}
: undefined),
executorSuggestions:
game.type === "Executor" ? (v.suggestions ?? []) : [],
emulatorSuggestions:
game.type === "Emulator" ? (v.suggestions ?? []) : [],
})),
}
: { data: [] },
@@ -549,7 +551,7 @@ class LibraryManager {
where: {
launches: {
some: {
executor: {
emulator: {
gameVersion: {
gameId,
},