Skip to content

Commit 3cf08c3

Browse files
committed
Add Biome linter/formatter and apply auto-fixes
- Configure Biome 2.4.7 with functional-style lint rules (useConst, noVar, useArrowFunction, noDoubleEquals, noUnusedImports) - Formatter: 2-space indent, single quotes, semicolons, 120 line width - Add lint/lint:fix/format npm scripts - Add lint step to pre-commit hook - Apply all safe auto-fixes: formatting, import organization, let-to-const, unused import removal - Fix noShadowRestrictedNames (escape -> escapeResult in ai.ts) - Fix useIterableCallbackReturn in ui.ts - Remove unused private canvas field from InputHandler
1 parent a971c8d commit 3cf08c3

File tree

109 files changed

+3217
-2614
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

109 files changed

+3217
-2614
lines changed

.husky/pre-commit

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
npm run lint
12
npm run typecheck
23
npm run test:coverage
34
npm run simulate all 25 --ci

biome.json

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
{
2+
"$schema": "https://biomejs.dev/schemas/2.4.7/schema.json",
3+
"formatter": {
4+
"indentStyle": "space",
5+
"indentWidth": 2,
6+
"lineWidth": 120
7+
},
8+
"javascript": {
9+
"formatter": {
10+
"quoteStyle": "single",
11+
"semicolons": "always",
12+
"trailingCommas": "all",
13+
"arrowParentheses": "always"
14+
}
15+
},
16+
"linter": {
17+
"rules": {
18+
"style": {
19+
"useConst": "error",
20+
"useTemplate": "warn",
21+
"useExponentiationOperator": "warn",
22+
"noNonNullAssertion": "off"
23+
},
24+
"complexity": {
25+
"useArrowFunction": "warn",
26+
"useFlatMap": "warn",
27+
"noForEach": "off"
28+
},
29+
"suspicious": {
30+
"noVar": "error",
31+
"noExplicitAny": "warn",
32+
"noDoubleEquals": "error"
33+
},
34+
"correctness": {
35+
"noUnusedVariables": "warn",
36+
"noUnusedImports": "error"
37+
}
38+
}
39+
},
40+
"files": {
41+
"includes": ["src/**/*.ts", "*.mjs"]
42+
}
43+
}

package-lock.json

Lines changed: 164 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,14 @@
1111
"test": "vitest run",
1212
"test:coverage": "vitest run --coverage",
1313
"test:watch": "vitest",
14+
"lint": "biome check src/",
15+
"lint:fix": "biome check --write src/",
16+
"format": "biome format --write src/",
1417
"simulate": "tsx scripts/simulate-ai.ts",
1518
"prepare": "husky"
1619
},
1720
"devDependencies": {
21+
"@biomejs/biome": "2.4.7",
1822
"@cloudflare/workers-types": "^4.20250214.0",
1923
"@types/node": "^25.5.0",
2024
"@types/ws": "^8.18.1",

src/client/audio.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ export function isMuted(): boolean {
1313
export function setMuted(m: boolean) {
1414
muted = m;
1515
// Persist preference
16-
try { localStorage.setItem('delta-v-mute', m ? '1' : '0'); } catch {}
16+
try {
17+
localStorage.setItem('delta-v-mute', m ? '1' : '0');
18+
} catch {}
1719
}
1820

1921
function getCtx(): AudioContext | null {

src/client/game-client-ai-flow.test.ts

Lines changed: 47 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,7 @@
11
import { describe, expect, it, vi } from 'vitest';
22

33
import { buildSolarSystemMap } from '../shared/map-data';
4-
import type {
5-
AstrogationOrder,
6-
CombatAttack,
7-
GameState,
8-
OrdnanceLaunch,
9-
PlayerState,
10-
Ship,
11-
} from '../shared/types';
4+
import type { AstrogationOrder, CombatAttack, GameState, OrdnanceLaunch, PlayerState, Ship } from '../shared/types';
125
import { deriveAIActionPlan } from './game-client-ai-flow';
136

147
function createShip(overrides: Partial<Ship> = {}): Ship {
@@ -76,11 +69,13 @@ describe('game-client-ai-flow', () => {
7669
const orders: AstrogationOrder[] = [{ shipId: 'ai-ship', burn: 2 }];
7770
const astrogation = vi.fn(() => orders);
7871

79-
expect(deriveAIActionPlan(createState({ phase: 'astrogation' }), 0, map, 'normal', {
80-
astrogation,
81-
ordnance: vi.fn(() => []),
82-
combat: vi.fn(() => []),
83-
})).toEqual({
72+
expect(
73+
deriveAIActionPlan(createState({ phase: 'astrogation' }), 0, map, 'normal', {
74+
astrogation,
75+
ordnance: vi.fn(() => []),
76+
combat: vi.fn(() => []),
77+
}),
78+
).toEqual({
8479
kind: 'astrogation',
8580
aiPlayer: 1,
8681
orders,
@@ -92,11 +87,13 @@ describe('game-client-ai-flow', () => {
9287
const map = buildSolarSystemMap();
9388
const launches: OrdnanceLaunch[] = [{ shipId: 'ai-ship', ordnanceType: 'mine' }];
9489

95-
expect(deriveAIActionPlan(createState({ phase: 'ordnance' }), 0, map, 'normal', {
96-
astrogation: vi.fn(() => []),
97-
ordnance: vi.fn(() => launches),
98-
combat: vi.fn(() => []),
99-
})).toEqual({
90+
expect(
91+
deriveAIActionPlan(createState({ phase: 'ordnance' }), 0, map, 'normal', {
92+
astrogation: vi.fn(() => []),
93+
ordnance: vi.fn(() => launches),
94+
combat: vi.fn(() => []),
95+
}),
96+
).toEqual({
10097
kind: 'ordnance',
10198
aiPlayer: 1,
10299
launches,
@@ -105,11 +102,13 @@ describe('game-client-ai-flow', () => {
105102
errorPrefix: 'AI ordnance error:',
106103
});
107104

108-
expect(deriveAIActionPlan(createState({ phase: 'ordnance' }), 0, map, 'normal', {
109-
astrogation: vi.fn(() => []),
110-
ordnance: vi.fn(() => []),
111-
combat: vi.fn(() => []),
112-
})).toEqual({
105+
expect(
106+
deriveAIActionPlan(createState({ phase: 'ordnance' }), 0, map, 'normal', {
107+
astrogation: vi.fn(() => []),
108+
ordnance: vi.fn(() => []),
109+
combat: vi.fn(() => []),
110+
}),
111+
).toEqual({
113112
kind: 'ordnance',
114113
aiPlayer: 1,
115114
launches: [],
@@ -123,32 +122,43 @@ describe('game-client-ai-flow', () => {
123122
const map = buildSolarSystemMap();
124123
const attacks: CombatAttack[] = [{ attackerIds: ['ai-ship'], targetId: 'player-ship' }];
125124

126-
expect(deriveAIActionPlan(createState({
127-
phase: 'combat',
128-
pendingAsteroidHazards: [{ shipId: 'ai-ship', hex: { q: 0, r: 0 } }],
129-
}), 0, map, 'normal')).toEqual({
125+
expect(
126+
deriveAIActionPlan(
127+
createState({
128+
phase: 'combat',
129+
pendingAsteroidHazards: [{ shipId: 'ai-ship', hex: { q: 0, r: 0 } }],
130+
}),
131+
0,
132+
map,
133+
'normal',
134+
),
135+
).toEqual({
130136
kind: 'beginCombat',
131137
aiPlayer: 1,
132138
errorPrefix: 'AI combat start error:',
133139
});
134140

135-
expect(deriveAIActionPlan(createState({ phase: 'combat' }), 0, map, 'normal', {
136-
astrogation: vi.fn(() => []),
137-
ordnance: vi.fn(() => []),
138-
combat: vi.fn(() => attacks),
139-
})).toEqual({
141+
expect(
142+
deriveAIActionPlan(createState({ phase: 'combat' }), 0, map, 'normal', {
143+
astrogation: vi.fn(() => []),
144+
ordnance: vi.fn(() => []),
145+
combat: vi.fn(() => attacks),
146+
}),
147+
).toEqual({
140148
kind: 'combat',
141149
aiPlayer: 1,
142150
attacks,
143151
skip: false,
144152
errorPrefix: 'AI combat error:',
145153
});
146154

147-
expect(deriveAIActionPlan(createState({ phase: 'combat' }), 0, map, 'normal', {
148-
astrogation: vi.fn(() => []),
149-
ordnance: vi.fn(() => []),
150-
combat: vi.fn(() => []),
151-
})).toEqual({
155+
expect(
156+
deriveAIActionPlan(createState({ phase: 'combat' }), 0, map, 'normal', {
157+
astrogation: vi.fn(() => []),
158+
ordnance: vi.fn(() => []),
159+
combat: vi.fn(() => []),
160+
}),
161+
).toEqual({
152162
kind: 'combat',
153163
aiPlayer: 1,
154164
attacks: [],

src/client/game-client-ai-flow.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,7 @@
1-
import { aiAstrogation, aiCombat, aiOrdnance, type AIDifficulty } from '../shared/ai';
1+
import { type AIDifficulty, aiAstrogation, aiCombat, aiOrdnance } from '../shared/ai';
22
import { SHIP_STATS } from '../shared/constants';
33
import { filterStateForPlayer } from '../shared/game-engine';
4-
import type {
5-
AstrogationOrder,
6-
CombatAttack,
7-
GameState,
8-
OrdnanceLaunch,
9-
SolarSystemMap,
10-
} from '../shared/types';
4+
import type { AstrogationOrder, CombatAttack, GameState, OrdnanceLaunch, SolarSystemMap } from '../shared/types';
115
import { hasOwnedPendingAsteroidHazards } from './game-client-local';
126

137
export interface AIDecisionGenerators {

0 commit comments

Comments
 (0)