feat: refactor utility functions for improved consistency and usability; consolidate parsing logic
This commit is contained in:
@@ -1,9 +1,7 @@
|
||||
import type { City, Nation } from '@sammo-ts/logic';
|
||||
import { asRecord, isRecord } from '@sammo-ts/common';
|
||||
|
||||
export const isRecord = (value: unknown): value is Record<string, unknown> =>
|
||||
value !== null && typeof value === 'object' && !Array.isArray(value);
|
||||
|
||||
export const asRecord = (value: unknown): Record<string, unknown> => (isRecord(value) ? value : {});
|
||||
export { asRecord, isRecord };
|
||||
|
||||
export const readNumber = (value: unknown, fallback = 0): number => {
|
||||
if (typeof value === 'number' && Number.isFinite(value)) {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { TurnSchedule } from '@sammo-ts/logic';
|
||||
import { parseOptionalBoolean, parseOptionalNumber } from '@sammo-ts/common';
|
||||
|
||||
import type { TurnRunBudget } from '../lifecycle/types.js';
|
||||
import { resolveDatabaseUrl } from '../scenario/databaseUrl.js';
|
||||
@@ -24,36 +25,11 @@ const DEFAULT_BUDGET: TurnRunBudget = {
|
||||
catchUpCap: 1,
|
||||
};
|
||||
|
||||
const parseNumber = (value: string | undefined): number | undefined => {
|
||||
if (!value) {
|
||||
return undefined;
|
||||
}
|
||||
const parsed = Number(value);
|
||||
if (!Number.isFinite(parsed)) {
|
||||
return undefined;
|
||||
}
|
||||
return parsed;
|
||||
};
|
||||
|
||||
const parseBoolean = (value: string | undefined): boolean | undefined => {
|
||||
if (!value) {
|
||||
return undefined;
|
||||
}
|
||||
const normalized = value.trim().toLowerCase();
|
||||
if (['1', 'true', 'yes', 'y', 'on'].includes(normalized)) {
|
||||
return true;
|
||||
}
|
||||
if (['0', 'false', 'no', 'n', 'off'].includes(normalized)) {
|
||||
return false;
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
const buildBudgetOverride = (env: NodeJS.ProcessEnv, override?: Partial<TurnRunBudget>): TurnRunBudget | undefined => {
|
||||
const budgetOverride: Partial<TurnRunBudget> = {
|
||||
budgetMs: parseNumber(env.TURN_BUDGET_MS),
|
||||
maxGenerals: parseNumber(env.TURN_MAX_GENERALS),
|
||||
catchUpCap: parseNumber(env.TURN_CATCH_UP_CAP),
|
||||
budgetMs: parseOptionalNumber(env.TURN_BUDGET_MS),
|
||||
maxGenerals: parseOptionalNumber(env.TURN_MAX_GENERALS),
|
||||
catchUpCap: parseOptionalNumber(env.TURN_CATCH_UP_CAP),
|
||||
...override,
|
||||
};
|
||||
|
||||
@@ -78,10 +54,10 @@ export const runTurnDaemonCli = async (options: TurnDaemonCliOptions = {}): Prom
|
||||
schema: env.GATEWAY_DB_SCHEMA ?? 'public',
|
||||
}));
|
||||
const budget = buildBudgetOverride(env, options.budget);
|
||||
const tickMinutes = options.tickMinutes ?? parseNumber(env.TURN_TICK_MINUTES);
|
||||
const enableDatabaseFlush = options.enableDatabaseFlush ?? parseBoolean(env.TURN_FLUSH_DB) ?? true;
|
||||
const pauseGateIntervalMs = parseNumber(env.TURN_PAUSE_GATE_MS);
|
||||
const adminActionIntervalMs = options.adminActionIntervalMs ?? parseNumber(env.TURN_ADMIN_ACTION_MS);
|
||||
const tickMinutes = options.tickMinutes ?? parseOptionalNumber(env.TURN_TICK_MINUTES);
|
||||
const enableDatabaseFlush = options.enableDatabaseFlush ?? parseOptionalBoolean(env.TURN_FLUSH_DB) ?? true;
|
||||
const pauseGateIntervalMs = parseOptionalNumber(env.TURN_PAUSE_GATE_MS);
|
||||
const adminActionIntervalMs = options.adminActionIntervalMs ?? parseOptionalNumber(env.TURN_ADMIN_ACTION_MS);
|
||||
|
||||
const runtime = await createTurnDaemonRuntime({
|
||||
profile,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { createGatewayPostgresConnector } from '@sammo-ts/infra';
|
||||
import { isRecord } from '@sammo-ts/common';
|
||||
|
||||
export type GatewayAdminActionStatus = 'REQUESTED' | 'APPLIED' | 'FAILED' | 'IGNORED';
|
||||
|
||||
@@ -53,9 +54,6 @@ export interface GatewayAdminActionConsumer {
|
||||
|
||||
const DEFAULT_POLL_MS = 5000;
|
||||
|
||||
const isRecord = (value: unknown): value is Record<string, unknown> =>
|
||||
Boolean(value) && typeof value === 'object' && !Array.isArray(value);
|
||||
|
||||
const normalizeMeta = (value: unknown): Record<string, unknown> => (isRecord(value) ? value : {});
|
||||
|
||||
const normalizeStatus = (value: unknown): GatewayAdminActionStatus | null => {
|
||||
|
||||
@@ -15,16 +15,12 @@ import {
|
||||
ITEM_KEYS,
|
||||
loadItemModules,
|
||||
} from '@sammo-ts/logic';
|
||||
import { asRecord } from '@sammo-ts/common';
|
||||
|
||||
const DEFAULT_GENERAL_GOLD = 1000;
|
||||
const DEFAULT_GENERAL_RICE = 1000;
|
||||
const DEFAULT_CREW_TYPE_ID = 1100;
|
||||
|
||||
const isRecord = (value: unknown): value is Record<string, unknown> =>
|
||||
value !== null && typeof value === 'object' && !Array.isArray(value);
|
||||
|
||||
const asRecord = (value: unknown): Record<string, unknown> => (isRecord(value) ? value : {});
|
||||
|
||||
const normalizeCode = (value: string | null | undefined): string | null => {
|
||||
if (!value || value === 'None') {
|
||||
return null;
|
||||
|
||||
@@ -21,7 +21,7 @@ import {
|
||||
resolveGeneralAction,
|
||||
} from '@sammo-ts/logic';
|
||||
import { LogCategory, LogFormat, LogScope } from '@sammo-ts/logic';
|
||||
import { LiteHashDRBG } from '@sammo-ts/common';
|
||||
import { asRecord, LiteHashDRBG } from '@sammo-ts/common';
|
||||
|
||||
import type { ConstraintContext, StateView } from '@sammo-ts/logic';
|
||||
|
||||
@@ -43,11 +43,6 @@ import type { AiReservedTurnProvider } from './ai/types.js';
|
||||
|
||||
const DEFAULT_ACTION = '휴식';
|
||||
|
||||
const isRecord = (value: unknown): value is Record<string, unknown> =>
|
||||
value !== null && typeof value === 'object' && !Array.isArray(value);
|
||||
|
||||
const asRecord = (value: unknown): Record<string, unknown> => (isRecord(value) ? value : {});
|
||||
|
||||
const resolveConstraintEnv = (
|
||||
world: TurnWorldState,
|
||||
scenarioMeta: ScenarioMeta | undefined,
|
||||
@@ -325,7 +320,7 @@ class WorldStateView implements StateView {
|
||||
}
|
||||
}
|
||||
|
||||
const extractArgsRecord = (value: unknown): Record<string, unknown> => (isRecord(value) ? value : {});
|
||||
const extractArgsRecord = (value: unknown): Record<string, unknown> => asRecord(value);
|
||||
|
||||
const buildConstraintContext = (
|
||||
general: TurnGeneral,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { createGamePostgresConnector, type InputJsonValue, type TurnEngineDatabaseClient } from '@sammo-ts/infra';
|
||||
import { isRecord } from '@sammo-ts/common';
|
||||
|
||||
export interface ReservedTurnEntry {
|
||||
action: string;
|
||||
@@ -22,9 +23,6 @@ const DEFAULT_NATION_TURNS = 12;
|
||||
|
||||
const asJson = (value: unknown): InputJsonValue => value as InputJsonValue;
|
||||
|
||||
const isRecord = (value: unknown): value is Record<string, unknown> =>
|
||||
value !== null && typeof value === 'object' && !Array.isArray(value);
|
||||
|
||||
const normalizeAction = (action: string | null | undefined): string =>
|
||||
action && action.length > 0 ? action : DEFAULT_TURN_ACTION;
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
} from '@sammo-ts/infra';
|
||||
import type { City, Nation, ScenarioConfig, ScenarioMeta, Troop, TriggerValue } from '@sammo-ts/logic';
|
||||
import { z } from 'zod';
|
||||
import { asRecord, isRecord } from '@sammo-ts/common';
|
||||
|
||||
import { getNextTickTime } from '../lifecycle/getNextTickTime.js';
|
||||
import type { MapLoaderOptions } from '../scenario/mapLoader.js';
|
||||
@@ -27,11 +28,6 @@ interface TurnWorldLoaderOptions {
|
||||
|
||||
type JsonRecord = Record<string, unknown>;
|
||||
|
||||
const isRecord = (value: unknown): value is JsonRecord =>
|
||||
value !== null && typeof value === 'object' && !Array.isArray(value);
|
||||
|
||||
const asRecord = (value: unknown): JsonRecord => (isRecord(value) ? value : {});
|
||||
|
||||
const asTriggerRecord = (value: unknown): Record<string, TriggerValue> =>
|
||||
isRecord(value) ? (value as Record<string, TriggerValue>) : {};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user