From 91ee7196332313518324cf7195f64d0e92b2cc8b Mon Sep 17 00:00:00 2001 From: Simeon Radivoev Date: Sun, 22 Mar 2026 16:34:33 +0200 Subject: [PATCH] feat: moved to npm package for the store --- src/bun/api/jobs/update-store.ts | 82 ++++++---------------- src/bun/api/store/services/gamesService.ts | 9 ++- src/shared/constants.ts | 1 + 3 files changed, 29 insertions(+), 63 deletions(-) diff --git a/src/bun/api/jobs/update-store.ts b/src/bun/api/jobs/update-store.ts index a842b1d..74872c3 100644 --- a/src/bun/api/jobs/update-store.ts +++ b/src/bun/api/jobs/update-store.ts @@ -1,80 +1,40 @@ import { ensureDir } from "fs-extra"; import { IJob, JobContext } from "../task-queue"; -import { getStoreFolder } from "../store/services/gamesService"; -import z from "zod"; +import { getStoreRootFolder } from "../store/services/gamesService"; +import { STORE_VERSION } from "@/shared/constants"; +import { tmpdir } from "node:os"; +import path from "node:path"; export default class UpdateStoreJob implements IJob { static id = "update-store" as const; - static origin = "https://github.com/simeonradivoev/gameflow-store.git"; - static branch = "master"; - static dataSchema = z.never(); + packageName: string; + registry: URL; + storeVersion: string; - async gitCommand (commands: string[], dir: string) + constructor() { - const proc = Bun.spawn(['git', ...commands], { - cwd: dir, - stdout: "pipe", - stderr: "pipe", - }); - - const [output] = await Promise.all([ - new Response(proc.stdout).text(), - proc.exited, - ]); - - return output.trim(); - } - - async isGitRepo (dir: string) - { - return (await this.gitCommand(["rev-parse", "--is-inside-work-tree"], dir)) === 'true'; - } - - async getOrigin (dir: string) - { - const origin = await this.gitCommand(["remote", "get-url", "origin"], dir); - return origin; - } - - async hasChanges (dir: string) - { - return (await this.gitCommand(["status", "--porcelain"], dir)).length > 0; + this.packageName = process.env.STORE_PACKAGE_NAME ?? "@simeonradivoev/gameflow-store"; + this.registry = new URL(process.env.STORE_REGISTRY ?? "https://registry.npmjs.org"); + this.storeVersion = process.env.STORE_VERSION ?? STORE_VERSION; } async start (context: JobContext) { if (process.env.CUSTOM_STORE_PATH) return; - const storeFolder = getStoreFolder(); + const tempCache = path.join(tmpdir(), "gameflow-bun-cache"); + const storeFolder = getStoreRootFolder(); await ensureDir(storeFolder); - context.setProgress(10); - if (await this.isGitRepo(storeFolder)) - { - const existingOrigin = await this.getOrigin(storeFolder); - if (existingOrigin !== UpdateStoreJob.origin) - { - throw new Error(`Git Repo in downloads is not valid. It has origin of ${existingOrigin}. Repo must be of ${UpdateStoreJob.origin}`); - } - // check for uncommitted changes - const status = await this.gitCommand([" status", "--porcelain"], storeFolder); - if (status.length > 0) - { - console.log("Cleaning local changes..."); - await this.gitCommand(["reset", "--hard"], storeFolder); - await this.gitCommand(["clean", "-fd"], storeFolder); + await Bun.spawn([process.execPath, "install", `${this.packageName}@${this.storeVersion}`, "--registry", this.registry.href], { + cwd: storeFolder, + stdout: 'pipe', + stderr: 'pipe', + env: { + BUN_BE_BUN: "1", + BUN_INSTALL_CACHE_DIR: tempCache } - - // fetch & reset to remote - await this.gitCommand(["fetch", "origin"], storeFolder); - await this.gitCommand(["reset", "--hard", `origin/${UpdateStoreJob.branch}`], storeFolder); - console.log("Shop Repo updated"); - } else - { - context.setProgress(50); - await this.gitCommand(["clone", "--depth", "1", "--branch", UpdateStoreJob.branch, UpdateStoreJob.origin, '.'], storeFolder); - context.setProgress(100); - } + }).exited; } } \ No newline at end of file diff --git a/src/bun/api/store/services/gamesService.ts b/src/bun/api/store/services/gamesService.ts index 3ebb355..9247823 100644 --- a/src/bun/api/store/services/gamesService.ts +++ b/src/bun/api/store/services/gamesService.ts @@ -75,11 +75,16 @@ export async function getStoreGameFromPath (path: string) return game; } +export function getStoreRootFolder () +{ + const downlodDir = config.get('downloadPath'); + return path.join(downlodDir, "store"); +} + export function getStoreFolder () { if (process.env.CUSTOM_STORE_PATH) return process.env.CUSTOM_STORE_PATH; - const downlodDir = config.get('downloadPath'); - return path.join(downlodDir, "store"); + return path.join(getStoreRootFolder(), "node_modules", process.env.STORE_PACKAGE_NAME ?? "@simeonradivoev/gameflow-store"); } export async function getStoreEmulatorPackage (id: string) diff --git a/src/shared/constants.ts b/src/shared/constants.ts index fe49793..a97a739 100644 --- a/src/shared/constants.ts +++ b/src/shared/constants.ts @@ -14,6 +14,7 @@ export const RPC_PORT = 8787; export const RPC_URL = (host: string) => `http://${host}:${RPC_PORT}`; export const EMULATORJS_URL = (host: string) => `http://${host}:${EMULATORJS_PORT}`; export const SOCKETS_URL = (host: string) => `ws://${host}:${RPC_PORT}`; +export const STORE_VERSION = "^0"; export const DefaultRommStaleTime = 60 * 1000; // A minute export interface GameMeta