refactor: moved queries to their own file
This commit is contained in:
parent
364bc9d0be
commit
cf6fff6fac
83 changed files with 1107 additions and 852 deletions
|
|
@ -1,4 +1,4 @@
|
|||
import Elysia, { sse, status } from "elysia";
|
||||
import Elysia, { status } from "elysia";
|
||||
import { config, events, jar, taskQueue } from "./app";
|
||||
import z from "zod";
|
||||
import { client } from "@clients/romm/client.gen";
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import auth from "./auth";
|
|||
|
||||
export default new Elysia({ prefix: "/api/romm" })
|
||||
.use([games, platforms, auth])
|
||||
.all("/*", async ({ request, params, set }) =>
|
||||
.all("/*", async ({ request, set }) =>
|
||||
{
|
||||
set.headers["cross-origin-resource-policy"] = 'cross-origin';
|
||||
|
||||
|
|
|
|||
|
|
@ -401,7 +401,7 @@ export default new Elysia()
|
|||
const res = await fetch(`https://cdn.emulatorjs.org/latest/data/cores/${params['*']}`);
|
||||
return res;
|
||||
})
|
||||
.get('/emulatorjs/data/*', async ({ params }) =>
|
||||
.get('/emulatorjs/data/*', async () =>
|
||||
{
|
||||
return status("Not Found");
|
||||
});
|
||||
|
|
@ -181,7 +181,7 @@ export async function getValidLaunchCommands (data: {
|
|||
'%FILENAME%': $.escape(path.basename(validFiles[0]))
|
||||
};
|
||||
|
||||
cmd = cmd.replace(/\%INJECT\%=(?<inject>[\w\%.\/\\]+)/g, (subscring, injectFile: string) =>
|
||||
cmd = cmd.replace(/\%INJECT\%=(?<inject>[\w\%.\/\\]+)/g, (_, injectFile: string) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
|
|||
|
|
@ -230,7 +230,7 @@ export default async function buildStatusResponse (source: string, id: string)
|
|||
dispose.forEach(f => f());
|
||||
};
|
||||
},
|
||||
cancel (reason)
|
||||
cancel ()
|
||||
{
|
||||
cleanup?.();
|
||||
cleanup = undefined;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import getFolderSize from "get-folder-size";
|
||||
import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { config, db, emulatorsDb } from "../../app";
|
||||
import { config, emulatorsDb } from "../../app";
|
||||
import { and, eq } from "drizzle-orm";
|
||||
import * as schema from "@schema/app";
|
||||
import { FrontEndGameType, FrontEndGameTypeDetailed, StoreGameType } from "@shared/constants";
|
||||
|
|
@ -103,15 +103,6 @@ export function convertLocalToFrontendDetailed (g: typeof schema.games.$inferSel
|
|||
|
||||
export async function convertStoreToFrontend (system: string, id: string, storeGame: StoreGameType): Promise<FrontEndGameType>
|
||||
{
|
||||
let size: number | null = null;
|
||||
try
|
||||
{
|
||||
const fileResponse = await fetch(storeGame.file, { method: 'HEAD' });
|
||||
size = Number(fileResponse.headers.get('content-length'));
|
||||
} catch (error)
|
||||
{
|
||||
console.error(error);
|
||||
}
|
||||
const rommSystem = await emulatorsDb.query.systemMappings.findFirst({
|
||||
where: and(eq(emulatorSchema.systemMappings.system, system), eq(emulatorSchema.systemMappings.source, 'romm'))
|
||||
});
|
||||
|
|
|
|||
|
|
@ -165,7 +165,7 @@ export class InstallJob implements IJob
|
|||
let bytesReceived = 0;
|
||||
|
||||
const progressStream = new Transform({
|
||||
transform (chunk, encoding, callback)
|
||||
transform (chunk, _, callback)
|
||||
{
|
||||
bytesReceived += chunk.length;
|
||||
if (totalBytes > 0)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { LoginJob } from "./login-job";
|
|||
import TwitchLoginJob from "./twitch-login-job";
|
||||
import UpdateStoreJob from "./update-store";
|
||||
|
||||
function registerJob<const Path extends string, TS, T extends { id: Path, dataSchema?: TS; }> (job: T, path: Path, dataSchema: TS)
|
||||
function registerJob<const Path extends string, TS, T extends { id: Path, dataSchema?: TS; }> (_job: T, path: Path, dataSchema: TS)
|
||||
{
|
||||
return new Elysia().ws(path, {
|
||||
body: z.discriminatedUnion('type', [
|
||||
|
|
@ -64,7 +64,7 @@ function registerJob<const Path extends string, TS, T extends { id: Path, dataSc
|
|||
{
|
||||
(ws.data as any).cleanup.forEach((d: Function) => d());
|
||||
},
|
||||
message (ws, message)
|
||||
message (_, message)
|
||||
{
|
||||
if (message.type === 'cancel')
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
|
||||
import * as appSchema from '@schema/app';
|
||||
import { findExec, findExecByName } from "../games/services/launchGameService";
|
||||
import { findExecByName } from "../games/services/launchGameService";
|
||||
import * as emulatorSchema from "@schema/emulators";
|
||||
import { eq, inArray } from 'drizzle-orm';
|
||||
import { customEmulators, db, emulatorsDb } from '../app';
|
||||
import fs from 'node:fs/promises';
|
||||
import { cores } from '../emulatorjs/emulatorjs';
|
||||
import { FrontEndEmulator } from '@/shared/constants';
|
||||
|
||||
/**
|
||||
* Get emulators based on local games. Only the ones we probably need.
|
||||
|
|
@ -77,117 +78,40 @@ export async function getRelevantEmulators ()
|
|||
systems.forEach(s => platformViability.set(s, true));
|
||||
}
|
||||
|
||||
return {
|
||||
emulator: emulator,
|
||||
path: execPath,
|
||||
const em: FrontEndEmulator & { isCritical: boolean; path?: { path: string, type: string; }; } = {
|
||||
name: emulator,
|
||||
exists: exists,
|
||||
logo: platform ? `/api/romm/platform/local/${platform}/cover` : '',
|
||||
systems: systems.map(s => platformLookup.get(s)).filter(s => !!s).map(e => ({ icon: `/api/romm/image/romm/assets/platforms/${e.es_slug}.svg`, name: e.platform_name ?? 'Unknown', id: e.es_slug ?? '' })),
|
||||
gameCount: 0,
|
||||
description: '',
|
||||
homepage: '',
|
||||
type: 'emulator',
|
||||
os: [process.platform as any],
|
||||
isCritical: false,
|
||||
path_cover: platform ? `/api/romm/platform/local/${platform}/cover` : null,
|
||||
systems: systems.map(s => platformLookup.get(s)).filter(s => !!s)
|
||||
path: execPath,
|
||||
};
|
||||
|
||||
return em;
|
||||
}));
|
||||
|
||||
finalEmulators.push({
|
||||
emulator: 'emulatorjs',
|
||||
name: 'emulatorjs',
|
||||
exists: true,
|
||||
path: { path: 'localhost', type: 'js' },
|
||||
path_cover: `/api/romm/image?url=${encodeURIComponent('https://emulatorjs.org/logo/EmulatorJS.png')}`,
|
||||
isCritical: false,
|
||||
systems: []
|
||||
logo: `/api/romm/image?url=${encodeURIComponent('https://emulatorjs.org/logo/EmulatorJS.png')}`,
|
||||
systems: [],
|
||||
gameCount: 0,
|
||||
type: 'emulator',
|
||||
description: '',
|
||||
homepage: '',
|
||||
os: [process.platform as any],
|
||||
isCritical: false
|
||||
});
|
||||
|
||||
return finalEmulators.map(e =>
|
||||
{
|
||||
e.isCritical = !e.systems.filter(s => s?.es_slug).some(s => !!platformViability.get(s?.es_slug!));
|
||||
e.isCritical = !e.systems.filter(s => s?.id).some(s => !!platformViability.get(s?.id!));
|
||||
return e;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Only emulators we strictly need based on local games. Emulator JS is included as bundled.
|
||||
* If there is even single emulator for a system don't include emulators for that system.
|
||||
*/
|
||||
/*export async function getMissingEmulators ()
|
||||
{
|
||||
const localGames = await db.query.games.findMany({
|
||||
columns: {
|
||||
platform_id: true,
|
||||
slug: true
|
||||
},
|
||||
with: {
|
||||
platform: {
|
||||
columns: {
|
||||
name: true,
|
||||
es_slug: true
|
||||
}
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
const platformLookup = new Map(localGames.map(g => [g.platform.es_slug, g]));
|
||||
const platformViability = new Map(localGames.map(g => [g.platform.es_slug, false]));
|
||||
|
||||
// all commands based on the local games
|
||||
const commands = await emulatorsDb.query.commands.findMany({
|
||||
columns: { command: true },
|
||||
where: inArray(emulatorSchema.commands.system, Array.from(new Set(localGames.filter(g => g.platform.es_slug).map(s => s.platform.es_slug!)))),
|
||||
with: { system: { columns: { name: true } } }
|
||||
});
|
||||
|
||||
// get all emulators in said commands
|
||||
const emulators = commands
|
||||
.flatMap(command =>
|
||||
{
|
||||
const matches = command.command.match(/(?<=%EMULATOR_)[\w-]+(?=%)/);
|
||||
if (!matches)
|
||||
{
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return matches?.map(m => ({ emulator: m, system: command.system?.name }));
|
||||
}
|
||||
).filter(c => !!c);
|
||||
|
||||
const groupedEmulators = Map.groupBy(emulators, ({ emulator }) => emulator);
|
||||
const finalEmulators = await Promise.all(Array.from(groupedEmulators.entries()).map(async ([emulator, system_slug]) =>
|
||||
{
|
||||
let execPath: { path: string; type: string, } | undefined;
|
||||
if (customEmulators.has(emulator))
|
||||
{
|
||||
execPath = { path: customEmulators.get(emulator), type: 'custom' };
|
||||
} else
|
||||
{
|
||||
execPath = await findExecByName(emulator);
|
||||
}
|
||||
|
||||
let platform: number | null | undefined = null;
|
||||
if (system_slug.length <= 1)
|
||||
{
|
||||
platform = platformLookup.get(system_slug[0].system)?.platform_id;
|
||||
}
|
||||
|
||||
// check if automatic or custom path found existing binary.
|
||||
// This might not be the actual emulator but I don't care.
|
||||
const exists = !!execPath && await fs.exists(execPath.path);
|
||||
const systems = Array.from(new Set(system_slug.map(s => s.system)));
|
||||
if (exists)
|
||||
{
|
||||
systems.forEach(s => platformViability.set(s, true));
|
||||
}
|
||||
|
||||
return {
|
||||
emulator: emulator,
|
||||
path: execPath,
|
||||
exists: exists,
|
||||
isCritical: false,
|
||||
path_cover: platform ? `/api/romm/platform/local/${platform}/cover` : null,
|
||||
systems: systems.map(s => platformLookup.get(s)).filter(s => !!s)
|
||||
};
|
||||
}));
|
||||
|
||||
return finalEmulators.map(e =>
|
||||
{
|
||||
e.isCritical = !e.systems.filter(s => s?.es_slug).some(s => !!platformViability.get(s?.es_slug!));
|
||||
return e;
|
||||
});
|
||||
}*/
|
||||
}
|
||||
|
|
@ -194,7 +194,8 @@ export const store = new Elysia({ prefix: '/api/store' })
|
|||
source: execPath?.type,
|
||||
location: execPath?.path
|
||||
},
|
||||
screenshots: screenshots.map(s => `/api/store/screenshot/emulator/${id}/${s}`)
|
||||
screenshots: screenshots.map(s => `/api/store/screenshot/emulator/${id}/${s}`),
|
||||
gameCount: 0
|
||||
};
|
||||
|
||||
return emulator;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
import { SERVER_PORT } from "@shared/constants";
|
||||
import path from 'node:path';
|
||||
import appInfo from '~/package.json';
|
||||
import { host } from "./utils/host";
|
||||
import { appPath } from "./utils";
|
||||
import Elysia, { file } from "elysia";
|
||||
import Elysia from "elysia";
|
||||
import cors from "@elysiajs/cors";
|
||||
import staticPlugin from "@elysiajs/static";
|
||||
|
||||
|
|
@ -17,11 +15,11 @@ export function RunBunServer ()
|
|||
'cross-origin-opener-policy': 'same-origin',
|
||||
'cross-origin-resource-policy': 'cross-origin'
|
||||
})
|
||||
.get("/", ({ set }) =>
|
||||
.get("/", () =>
|
||||
{
|
||||
return Bun.file(appPath("./dist/index.html"));
|
||||
})
|
||||
.get('/emulatorjs', ({ set }) =>
|
||||
.get('/emulatorjs', () =>
|
||||
{
|
||||
return Bun.file(appPath('./dist/emulatorjs/index.html'));
|
||||
})
|
||||
|
|
|
|||
|
|
@ -41,7 +41,6 @@ export async function BuildParams (data: BrowserParams)
|
|||
|
||||
args.push(`--app=${SERVER_URL(host)}`);
|
||||
args.push(`--app-id=gameflow`);
|
||||
args.push(`--force-app-mode`);
|
||||
args.push('--no-default-browser-check');
|
||||
args.push('--new-instance');
|
||||
args.push('--no-first-run');
|
||||
|
|
|
|||
|
|
@ -27,11 +27,6 @@ interface SpawnBrowserOptions
|
|||
ipc?: (message: string) => void;
|
||||
}
|
||||
|
||||
interface SpawnLastInfo
|
||||
{
|
||||
PID: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Spawns a browser process with proper handling for different installation types.
|
||||
*
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue