1
0

Game loads and functions

This commit is contained in:
James Ketr 2025-10-06 11:44:59 -07:00
parent 873c229275
commit 2c15f57ca9
10 changed files with 60 additions and 25 deletions

View File

@ -2,10 +2,10 @@
import fetch from 'node-fetch';
import WebSocket from 'ws';
import fs from 'fs';
import calculateLongestRoad from './longest-road.js';
import calculateLongestRoad from './longest-road';
import { getValidRoads, getValidCorners } from '../util/validLocations.js';
import { layout, staticData } from '../util/layout.js';
import { getValidRoads, getValidCorners } from '../util/validLocations';
import { layout, staticData } from '../util/layout';
const version = '0.0.1';

View File

@ -1,5 +1,5 @@
// @ts-nocheck
import { layout } from '../util/layout.js';
import { layout } from '../util/layout';
const processCorner = (game: any, color: string, cornerIndex: number, placedCorner: any): number => {
/* If this corner is allocated and isn't assigned to the walking color, skip it */

View File

@ -41,7 +41,7 @@ app.use((req: express.Request, res: express.Response, next: express.NextFunction
import expressWs from 'express-ws';
expressWs(app, server);
require("./console-line.js"); /* Monkey-patch console.log with line numbers */
require("./console-line"); /* Monkey-patch console.log with line numbers */
const frontendPath = (config.get("frontendPath") as string).replace(/\/$/, "") + "/",
serverConfig = config.get("server") as any;

View File

@ -5,14 +5,14 @@ import { readFile, writeFile, mkdir } from 'fs/promises';
import fs from 'fs';
import randomWords from 'random-words';
import equal from 'fast-deep-equal';
import { layout, staticData } from '../util/layout.js';
import { layout, staticData } from '../util/layout';
import basePath from '../basepath';
import { getValidRoads, getValidCorners, isRuleEnabled } from '../util/validLocations.js';
import { Player } from './games/types.js';
import { normalizeIncoming, shuffleArray } from './games/utils.js';
import type { GameState } from './games/state.js';
import { serializeGame, deserializeGame, cloneGame } from './games/serialize.js';
import { getValidRoads, getValidCorners, isRuleEnabled } from '../util/validLocations';
import { Player } from './games/types';
import { normalizeIncoming, shuffleArray } from './games/utils';
import type { GameState } from './games/state';
import { serializeGame, deserializeGame, cloneGame } from './games/serialize';
const router = express.Router();
@ -31,7 +31,7 @@ const debug = {
// normalizeIncoming imported from './games/utils.ts'
import { initGameDB } from './games/store.js';
import { initGameDB } from './games/store';
let gameDB: any;
initGameDB().then((db) => {

View File

@ -1,4 +1,4 @@
import type { GameState } from './state.js';
import type { GameState } from './state';
export function serializeGame(game: GameState): string {
// Use a deterministic JSON serializer for snapshots; currently use JSON.stringify

View File

@ -1,4 +1,4 @@
import { Player } from './types.js';
import { Player } from './types';
export interface PlacementCorner {
color?: string | null;

View File

@ -8,9 +8,23 @@ import type { GameState } from './state.js';
export async function initGameDB(): Promise<any> {
// dynamic import to preserve original runtime ordering
// path is relative to this file (routes/games)
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore - dynamic import of runtime DB module; resolved at runtime inside container
const mod = await import('../db/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));

View File

@ -18,7 +18,7 @@ app.use(cookieParser());
expressWs(app, server);
require("../console-line.js"); /* Monkey-patch console.log with line numbers */
require("../console-line"); /* Monkey-patch console.log with line numbers */
// Temporary debug routes (dev-only). Mount before static so we can
// inspect what the server receives for base-prefixed requests.
@ -26,7 +26,7 @@ try {
// import the debug router using ESM style; fallback to require at runtime if needed
// (some dev environments may still emit JS commonjs files)
// eslint-disable-next-line @typescript-eslint/no-var-requires
const debugRouter = require("../routes/debug.js").default || require("../routes/debug.js");
const debugRouter = require("../routes/debug").default || require("../routes/debug");
app.use(basePath, debugRouter);
} catch (e: any) {
console.error('Failed to mount debug routes (src):', e && e.stack || e);
@ -53,7 +53,7 @@ app.set("trust proxy", true);
app.set("basePath", basePath);
// basepath is a simple exported string
// eslint-disable-next-line @typescript-eslint/no-var-requires
const basepathRouter = require("../routes/basepath.js").default || require("../routes/basepath.js");
const basepathRouter = require("../routes/basepath").default || require("../routes/basepath");
app.use(basePath, basepathRouter);
/* Handle static files first so excessive logging doesn't occur */
@ -61,7 +61,7 @@ app.use(basePath, express.static(frontendPath, { index: false }));
// index route (may be ESM default export)
// eslint-disable-next-line @typescript-eslint/no-var-requires
const index = require("../routes/index.js").default || require("../routes/index.js");
const index = require("../routes/index").default || require("../routes/index");
if (config.has("admin")) {
const admin = config.get("admin");
@ -70,7 +70,7 @@ if (config.has("admin")) {
// games router
// eslint-disable-next-line @typescript-eslint/no-var-requires
const gamesRouter = require("../routes/games.js").default || require("../routes/games.js");
const gamesRouter = require("../routes/games").default || require("../routes/games");
app.use(`${basePath}api/v1/games`, gamesRouter);
/* Allow loading of the app w/out being logged in */
@ -95,11 +95,11 @@ process.on('SIGINT', () => {
// database initializers
// eslint-disable-next-line @typescript-eslint/no-var-requires
require("../db/games.js").then(function(_db: any) {
Promise.resolve((require("../db/games") as any).default || require("../db/games")).then(function(_db: any) {
// games DB initialized
}).then(function() {
// eslint-disable-next-line @typescript-eslint/no-var-requires
return require("../db/users.js").then(function(_db: any) {
return Promise.resolve((require("../db/users") as any).default || require("../db/users")).then(function(_db: any) {
// users DB initialized
});
}).then(function() {

21
server/types/db-modules.d.ts vendored Normal file
View File

@ -0,0 +1,21 @@
declare module '../db/games' {
const value: any;
export default value;
}
declare module '../db/games.js' {
const value: any;
export default value;
}
declare module '../db/users' {
const value: any;
export default value;
}
declare module '../db/users.js' {
const value: any;
export default value;
}
export {};

View File

@ -1,4 +1,4 @@
import { layout } from './layout.js';
import { layout } from './layout';
const isRuleEnabled = (game: any, rule: string): boolean => {
return rule in game.rules && game.rules[rule].enabled;