월 경계, 전투 기술 상한, 연감과 베팅·설문·경매 정산 순서를 Ref 계약에 맞춘다.\n\n시나리오 일반 풀을 ENGINE mutation과 logical tick 기반으로 직렬화하고 914·915 catalog 및 조건부 100기 pool 실행 경계를 추가한다.\n\n경매 worker는 세대별 durable event만 만들고 ENGINE이 row lock 후 상태 전이와 정산을 단일 transaction으로 소유한다.
46 lines
1.6 KiB
TypeScript
46 lines
1.6 KiB
TypeScript
import { execFileSync } from 'node:child_process';
|
|
import { existsSync } from 'node:fs';
|
|
import path from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
|
|
const CORE_REPOSITORY_ROOT = fileURLToPath(new URL('../../../', import.meta.url));
|
|
|
|
const refSourceCandidates = (): string[] => {
|
|
if (process.env.SAMMO_REF_ROOT) {
|
|
return [path.resolve(process.env.SAMMO_REF_ROOT)];
|
|
}
|
|
|
|
const candidates = [path.resolve(CORE_REPOSITORY_ROOT, '..', 'ref', 'sam')];
|
|
try {
|
|
const commonDirectory = execFileSync('git', ['rev-parse', '--path-format=absolute', '--git-common-dir'], {
|
|
cwd: CORE_REPOSITORY_ROOT,
|
|
encoding: 'utf8',
|
|
stdio: ['ignore', 'pipe', 'ignore'],
|
|
}).trim();
|
|
candidates.push(path.resolve(path.dirname(commonDirectory), '..', 'ref', 'sam'));
|
|
} catch {
|
|
// The ordinary sibling checkout remains the fallback outside a Git worktree.
|
|
}
|
|
|
|
return [...new Set(candidates)];
|
|
};
|
|
|
|
export const hasRefSourceRoot = (): boolean => {
|
|
if (process.env.SAMMO_REQUIRE_REF_SOURCE === '1' || process.env.SAMMO_REF_ROOT) {
|
|
return true;
|
|
}
|
|
return refSourceCandidates().some((candidate) => existsSync(candidate));
|
|
};
|
|
|
|
export const resolveRefSourceRoot = (): string => {
|
|
const candidates = refSourceCandidates();
|
|
const resolvedRoot = candidates.find((candidate) => existsSync(candidate));
|
|
if (!resolvedRoot) {
|
|
if (process.env.SAMMO_REF_ROOT) {
|
|
throw new Error(`SAMMO_REF_ROOT does not exist: ${candidates[0]}`);
|
|
}
|
|
throw new Error(`Ref source checkout was not found. Checked: ${candidates.join(', ')}`);
|
|
}
|
|
return resolvedRoot;
|
|
};
|