11import { useReducer , type ActionDispatch } from "react" ;
22
3- import getRandomWord from "./getRandomWord " ;
3+ import getRandomElement from "./util/getRandomElement " ;
44
5- export type State =
5+ export type State = Readonly <
66 | {
77 phase : "pre-game" ;
8+ wordPack : readonly string [ ] | null ;
89 }
910 | {
1011 phase : "in-game" ;
1112 goal : string ;
1213 guess : string ;
14+ wordPack : readonly string [ ] ;
1315 }
1416 | {
1517 phase : "post-game" ;
1618 goal : string ;
17- } ;
19+ wordPack : readonly string [ ] ;
20+ }
21+ > ;
1822
1923export function getInitialState ( ) : State {
20- return { phase : "pre-game" } ;
24+ return { phase : "pre-game" , wordPack : null } ;
2125}
2226
2327export type Action =
28+ | { type : "load-data" ; wordPack : readonly string [ ] }
2429 | { type : "start-game" }
2530 | { type : "update-guess" ; newGuess : string } ;
2631
2732export function reducer ( state : State , action : Action ) : State {
2833 switch ( action . type ) {
34+ case "load-data" : {
35+ // No-op if not in pre-game phase.
36+ if ( state . phase !== "pre-game" ) {
37+ return state ;
38+ }
39+
40+ return { ...state , wordPack : action . wordPack } ;
41+ }
42+
2943 case "start-game" : {
3044 // No-op if already in a game.
3145 if ( state . phase === "in-game" ) {
3246 return state ;
3347 }
3448
49+ // No-op if data is not loaded.
50+ const { wordPack } = state ;
51+ if ( wordPack == null ) {
52+ return state ;
53+ }
54+
3555 return {
3656 phase : "in-game" ,
37- goal : getRandomWord ( ) ,
57+ goal : getRandomElement ( wordPack ) ,
3858 guess : "" ,
59+ wordPack,
3960 } ;
4061 }
4162
@@ -46,7 +67,11 @@ export function reducer(state: State, action: Action): State {
4667 }
4768
4869 if ( action . newGuess === state . goal ) {
49- return { phase : "post-game" , goal : state . goal } ;
70+ return {
71+ phase : "post-game" ,
72+ goal : state . goal ,
73+ wordPack : state . wordPack ,
74+ } ;
5075 }
5176
5277 return { ...state , guess : action . newGuess } ;
0 commit comments