import { clampDiceCount, createInitialDiceRollState, formatDiceNotation, isDiceSides, rollDiceValues, type DiceRollEvent, type DiceRollState, } from '../../shared/types/diceRoll'; export class DiceRollSessionStore { private state: DiceRollState = createInitialDiceRollState(); getState(): DiceRollState { return this.state; } clear(): DiceRollState { this.state = createInitialDiceRollState(); return this.state; } dispatch(event: DiceRollEvent): DiceRollState { switch (event.kind) { case 'clear': { if (!this.state.active && this.state.values.length === 0) return this.state; this.state = { ...createInitialDiceRollState(), revision: this.state.revision + 1, }; return this.state; } case 'hideOverlay': { if (!this.state.active) return this.state; this.state = { ...this.state, revision: this.state.revision + 1, active: false, startedAt: null, }; return this.state; } case 'roll': { if (!isDiceSides(event.sides)) return this.state; const count = clampDiceCount(event.count); const values = rollDiceValues(count, event.sides); const total = values.reduce((a, b) => a + b, 0); this.state = { revision: this.state.revision + 1, active: true, notation: formatDiceNotation(count, event.sides), values, total, startedAt: Date.now(), }; return this.state; } default: { const _exhaustive: never = event; return _exhaustive; } } } }