import type { GameState } from './state.js'; /** * Thin game DB initializer / accessor. * This currently returns the underlying db module (for runtime compatibility) * and is the single place to add typed helper methods for game persistence. */ export async function initGameDB(): Promise { // dynamic import to preserve original runtime ordering // path is relative to this file (routes/games) // Prefer synchronous require at runtime when available to avoid TS module resolution // issues during type-checking. Declare require to keep TypeScript happy. let mod: any; try { mod = (globalThis as any).require('../db/games'); } catch (e) { // If require isn't available (very unusual in our Node container), // return a safe no-op DB object rather than attempting a dynamic import. // This keeps runtime behavior unchanged in the normal case and avoids // needing // @ts-ignore for module resolution during type-checking. return { sequelize: undefined, Sequelize: undefined, getGameById: async (_id: string | number) => null, saveGameState: async (_id: string | number, _state: GameState) => { /* no-op */ } } as any; } // If the module uses default export, prefer it const db = (mod && (mod.default || mod)); // attach typed helper placeholders (will be implemented incrementally) if (!db.getGameById) { db.getGameById = async (id: string | number): Promise => { // fallback: try to query by id using raw SQL if sequelize is available if (db && db.sequelize) { try { const rows = await db.sequelize.query('SELECT state FROM games WHERE id=:id', { replacements: { id }, type: db.Sequelize.QueryTypes.SELECT }); if (rows && rows.length) { const r = rows[0] as any; // state may be stored as text or JSON if (typeof r.state === 'string') { try { return JSON.parse(r.state) as GameState; } catch (e) { return null; } } return r.state as GameState; } } catch (e) { // ignore and fallthrough } } return null; }; } if (!db.saveGameState) { db.saveGameState = async (id: string | number, state: GameState): Promise => { if (db && db.sequelize) { const payload = JSON.stringify(state); try { await db.sequelize.query('UPDATE games SET state=:state WHERE id=:id', { replacements: { id, state: payload } }); } catch (e) { // if update failed, attempt insert try { await db.sequelize.query('INSERT INTO games (id, state) VALUES(:id, :state)', { replacements: { id, state: payload } }); } catch (err) { // swallow; callers should handle missing persistence } } } }; } return db; }