Break import cycle in domain persistent-damage modules

Extract persistent damage types and definitions into a leaf module so
events.ts and types.ts no longer import back into persistent-damage.ts.
Enable oxlint import/no-cycle (whole workspace via root tsconfig) to
keep cycles out.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Lukas
2026-07-04 13:35:14 +02:00
co-authored by Claude Fable 5
parent aa5555ef86
commit 78079bf1b2
7 changed files with 99 additions and 84 deletions
+2 -1
View File
@@ -1,6 +1,6 @@
{
"$schema": "https://raw.githubusercontent.com/nicolo-ribaudo/tc39-proposal-type-annotations/refs/heads/main/packages/oxlint/configuration_file_schema.json",
"plugins": ["typescript", "unicorn", "jest"],
"plugins": ["typescript", "unicorn", "jest", "import"],
"categories": {},
"rules": {
"typescript/no-unnecessary-type-assertion": "error",
@@ -8,6 +8,7 @@
"typescript/prefer-regexp-exec": "error",
"unicorn/prefer-string-replace-all": "error",
"unicorn/prefer-string-raw": "error",
"import/no-cycle": "error",
"jest/expect-expect": [
"error",
{
+2 -2
View File
@@ -44,10 +44,10 @@
"knip": "knip",
"jscpd": "jscpd",
"jsinspect": "jsinspect -c .jsinspectrc apps/web/src packages/domain/src packages/application/src",
"oxlint": "oxlint --tsconfig apps/web/tsconfig.json --type-aware --deny-warnings",
"oxlint": "oxlint --tsconfig tsconfig.json --type-aware --deny-warnings",
"check:ignores": "node scripts/check-lint-ignores.mjs",
"check:classnames": "node scripts/check-cn-classnames.mjs",
"check:props": "node scripts/check-component-props.mjs",
"check": "pnpm audit --audit-level=high && knip && biome check . && node scripts/check-lint-ignores.mjs && node scripts/check-cn-classnames.mjs && node scripts/check-component-props.mjs && jscpd && pnpm jsinspect && tsc --build && oxlint --tsconfig apps/web/tsconfig.json --type-aware --deny warnings && vitest run"
"check": "pnpm audit --audit-level=high && knip && biome check . && node scripts/check-lint-ignores.mjs && node scripts/check-cn-classnames.mjs && node scripts/check-component-props.mjs && jscpd && pnpm jsinspect && tsc --build && oxlint --tsconfig tsconfig.json --type-aware --deny warnings && vitest run"
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
import type { ConditionId } from "./conditions.js";
import type { CreatureId } from "./creature-types.js";
import type { PersistentDamageType } from "./persistent-damage.js";
import type { PersistentDamageType } from "./persistent-damage-types.js";
import type { PlayerCharacterId } from "./player-character-types.js";
import type { CombatantId } from "./types.js";
@@ -0,0 +1,78 @@
export const PERSISTENT_DAMAGE_TYPES = [
"fire",
"bleed",
"acid",
"cold",
"electricity",
"poison",
"mental",
"force",
"void",
"spirit",
"vitality",
"piercing",
] as const;
export type PersistentDamageType = (typeof PERSISTENT_DAMAGE_TYPES)[number];
export const VALID_PERSISTENT_DAMAGE_TYPES: ReadonlySet<string> = new Set(
PERSISTENT_DAMAGE_TYPES,
);
export interface PersistentDamageEntry {
readonly type: PersistentDamageType;
readonly formula: string;
}
export interface PersistentDamageDefinition {
readonly type: PersistentDamageType;
readonly label: string;
readonly iconName: string;
readonly color: string;
}
export const PERSISTENT_DAMAGE_DEFINITIONS: readonly PersistentDamageDefinition[] =
[
{ type: "fire", label: "Fire", iconName: "Flame", color: "orange" },
{ type: "bleed", label: "Bleed", iconName: "Droplets", color: "red" },
{
type: "acid",
label: "Acid",
iconName: "FlaskConical",
color: "lime",
},
{ type: "cold", label: "Cold", iconName: "Snowflake", color: "sky" },
{
type: "electricity",
label: "Electricity",
iconName: "Zap",
color: "yellow",
},
{
type: "poison",
label: "Poison",
iconName: "Droplet",
color: "green",
},
{
type: "mental",
label: "Mental",
iconName: "BrainCog",
color: "pink",
},
{ type: "force", label: "Force", iconName: "Orbit", color: "indigo" },
{ type: "void", label: "Void", iconName: "Eclipse", color: "purple" },
{ type: "spirit", label: "Spirit", iconName: "Wind", color: "neutral" },
{
type: "vitality",
label: "Vitality",
iconName: "Sparkle",
color: "amber",
},
{
type: "piercing",
label: "Piercing",
iconName: "Sword",
color: "neutral",
},
];
+13 -77
View File
@@ -1,4 +1,10 @@
import type { DomainEvent } from "./events.js";
import {
PERSISTENT_DAMAGE_DEFINITIONS,
type PersistentDamageEntry,
type PersistentDamageType,
VALID_PERSISTENT_DAMAGE_TYPES,
} from "./persistent-damage-types.js";
import {
type CombatantId,
type DomainError,
@@ -7,84 +13,14 @@ import {
isDomainError,
} from "./types.js";
export const PERSISTENT_DAMAGE_TYPES = [
"fire",
"bleed",
"acid",
"cold",
"electricity",
"poison",
"mental",
"force",
"void",
"spirit",
"vitality",
"piercing",
] as const;
export type PersistentDamageType = (typeof PERSISTENT_DAMAGE_TYPES)[number];
export const VALID_PERSISTENT_DAMAGE_TYPES: ReadonlySet<string> = new Set(
export {
PERSISTENT_DAMAGE_DEFINITIONS,
PERSISTENT_DAMAGE_TYPES,
);
export interface PersistentDamageEntry {
readonly type: PersistentDamageType;
readonly formula: string;
}
export interface PersistentDamageDefinition {
readonly type: PersistentDamageType;
readonly label: string;
readonly iconName: string;
readonly color: string;
}
export const PERSISTENT_DAMAGE_DEFINITIONS: readonly PersistentDamageDefinition[] =
[
{ type: "fire", label: "Fire", iconName: "Flame", color: "orange" },
{ type: "bleed", label: "Bleed", iconName: "Droplets", color: "red" },
{
type: "acid",
label: "Acid",
iconName: "FlaskConical",
color: "lime",
},
{ type: "cold", label: "Cold", iconName: "Snowflake", color: "sky" },
{
type: "electricity",
label: "Electricity",
iconName: "Zap",
color: "yellow",
},
{
type: "poison",
label: "Poison",
iconName: "Droplet",
color: "green",
},
{
type: "mental",
label: "Mental",
iconName: "BrainCog",
color: "pink",
},
{ type: "force", label: "Force", iconName: "Orbit", color: "indigo" },
{ type: "void", label: "Void", iconName: "Eclipse", color: "purple" },
{ type: "spirit", label: "Spirit", iconName: "Wind", color: "neutral" },
{
type: "vitality",
label: "Vitality",
iconName: "Sparkle",
color: "amber",
},
{
type: "piercing",
label: "Piercing",
iconName: "Sword",
color: "neutral",
},
];
type PersistentDamageDefinition,
type PersistentDamageEntry,
type PersistentDamageType,
VALID_PERSISTENT_DAMAGE_TYPES,
} from "./persistent-damage-types.js";
export interface PersistentDamageSuccess {
readonly encounter: Encounter;
+2 -2
View File
@@ -2,8 +2,8 @@ import type { ConditionEntry, ConditionId } from "./conditions.js";
import { VALID_CONDITION_IDS } from "./conditions.js";
import { creatureId } from "./creature-types.js";
import { VALID_CR_VALUES } from "./encounter-difficulty.js";
import type { PersistentDamageEntry } from "./persistent-damage.js";
import { VALID_PERSISTENT_DAMAGE_TYPES } from "./persistent-damage.js";
import type { PersistentDamageEntry } from "./persistent-damage-types.js";
import { VALID_PERSISTENT_DAMAGE_TYPES } from "./persistent-damage-types.js";
import {
playerCharacterId,
VALID_PLAYER_COLORS,
+1 -1
View File
@@ -7,7 +7,7 @@ export function combatantId(id: string): CombatantId {
import type { ConditionEntry } from "./conditions.js";
import type { CreatureId } from "./creature-types.js";
import type { PersistentDamageEntry } from "./persistent-damage.js";
import type { PersistentDamageEntry } from "./persistent-damage-types.js";
import type { PlayerCharacterId } from "./player-character-types.js";
export interface Combatant {