@hellacardgames/speed 0.8.1 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/dist/ClientState-Dx8UvhMt.d.cts +111 -0
  2. package/dist/ClientState-Dx8UvhMt.d.cts.map +1 -0
  3. package/dist/ClientState-Dx8UvhMt.d.mts +111 -0
  4. package/dist/ClientState-Dx8UvhMt.d.mts.map +1 -0
  5. package/dist/client/index.cjs +60 -10
  6. package/dist/client/index.cjs.map +1 -1
  7. package/dist/client/index.d.cts +89 -14
  8. package/dist/client/index.d.cts.map +1 -1
  9. package/dist/client/index.d.mts +89 -14
  10. package/dist/client/index.d.mts.map +1 -1
  11. package/dist/client/index.mjs +60 -10
  12. package/dist/client/index.mjs.map +1 -1
  13. package/dist/manager/index.cjs +2 -2
  14. package/dist/manager/index.d.cts +140 -2
  15. package/dist/manager/index.d.cts.map +1 -0
  16. package/dist/manager/index.d.mts +140 -2
  17. package/dist/manager/index.d.mts.map +1 -0
  18. package/dist/manager/index.mjs +2 -2
  19. package/dist/{manager-0r8lvLRR.cjs → manager-B7gHPSPL.cjs} +70 -154
  20. package/dist/manager-B7gHPSPL.cjs.map +1 -0
  21. package/dist/{manager-B32oi0dB.mjs → manager-C6kRM9IW.mjs} +70 -154
  22. package/dist/manager-C6kRM9IW.mjs.map +1 -0
  23. package/dist/server/index.cjs +45 -165
  24. package/dist/server/index.cjs.map +1 -1
  25. package/dist/server/index.d.cts +149 -3
  26. package/dist/server/index.d.cts.map +1 -0
  27. package/dist/server/index.d.mts +149 -3
  28. package/dist/server/index.d.mts.map +1 -0
  29. package/dist/server/index.mjs +45 -165
  30. package/dist/server/index.mjs.map +1 -1
  31. package/package.json +2 -2
  32. package/dist/index-CVbiOmI3.d.mts +0 -125
  33. package/dist/index-CVbiOmI3.d.mts.map +0 -1
  34. package/dist/index-DOimW07r.d.cts +0 -125
  35. package/dist/index-DOimW07r.d.cts.map +0 -1
  36. package/dist/index-DlRknHKq.d.cts +0 -247
  37. package/dist/index-DlRknHKq.d.cts.map +0 -1
  38. package/dist/index-DlRknHKq.d.mts +0 -247
  39. package/dist/index-DlRknHKq.d.mts.map +0 -1
  40. package/dist/manager-0r8lvLRR.cjs.map +0 -1
  41. package/dist/manager-B32oi0dB.mjs.map +0 -1
@@ -1,247 +0,0 @@
1
- import { ManagerBase } from "@hellacardgames/lib";
2
- //#region src/game/types/Card.d.ts
3
- type Card = {
4
- readonly id: string;
5
- readonly rank: 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14;
6
- readonly suite: "clubs" | "diamonds" | "hearts" | "spades";
7
- };
8
- //#endregion
9
- //#region src/game/types/ChatMessage.d.ts
10
- type ChatMessage = {
11
- readonly id: string;
12
- readonly username: string;
13
- readonly text: string;
14
- };
15
- //#endregion
16
- //#region src/game/types/GameEvent.d.ts
17
- type GameEvent = {
18
- readonly type: "canPlayAtUpdated";
19
- readonly id: string;
20
- readonly canPlayAt: number;
21
- } | {
22
- readonly type: "cardDrawnFromSidePileToCenterPile";
23
- readonly id: string;
24
- readonly username: string;
25
- readonly card: Card;
26
- } | {
27
- readonly type: "cardPlayed";
28
- readonly id: string;
29
- readonly username: string;
30
- readonly card: Card;
31
- readonly isForOtherPlayerPile: boolean;
32
- } | {
33
- readonly type: "chat";
34
- readonly id: string;
35
- readonly message: ChatMessage;
36
- } | {
37
- readonly type: "drewCard";
38
- readonly id: string;
39
- readonly card: Card;
40
- } | {
41
- readonly type: "expirationUpdated";
42
- readonly id: string;
43
- readonly expiresAt: number;
44
- } | {
45
- readonly type: "gameCompleted";
46
- readonly id: string;
47
- } | {
48
- readonly type: "gameForfeited";
49
- readonly id: string;
50
- } | {
51
- readonly type: "gameStarted";
52
- readonly id: string;
53
- } | {
54
- readonly type: "handInitialized";
55
- readonly id: string;
56
- readonly cards: readonly Card[];
57
- } | {
58
- readonly type: "playerCenterPileInitialized";
59
- readonly id: string;
60
- readonly username: string;
61
- readonly card: Card;
62
- } | {
63
- readonly type: "playerDrawPileInitialized";
64
- readonly id: string;
65
- readonly username: string;
66
- readonly numCards: number;
67
- } | {
68
- readonly type: "playerDrewCard";
69
- readonly id: string;
70
- readonly username: string;
71
- } | {
72
- readonly type: "playerHandInitialized";
73
- readonly id: string;
74
- readonly username: string;
75
- readonly numCards: number;
76
- } | {
77
- readonly type: "playerJoined";
78
- readonly id: string;
79
- readonly username: string;
80
- } | {
81
- readonly type: "playerLeft";
82
- readonly id: string;
83
- readonly username: string;
84
- } | {
85
- readonly type: "playerSidePileInitialized";
86
- readonly id: string;
87
- readonly username: string;
88
- readonly numCards: number;
89
- };
90
- //#endregion
91
- //#region src/game/types/Player.d.ts
92
- type Player$1 = {
93
- readonly id: string;
94
- readonly userId: string;
95
- readonly username: string;
96
- readonly events: GameEvent[];
97
- readonly hand: Card[];
98
- readonly drawPile: Card[];
99
- readonly sidePile: Card[];
100
- readonly centerPile: Card[];
101
- hasNoPlayableCards: boolean;
102
- };
103
- //#endregion
104
- //#region src/game/types/Game.d.ts
105
- type Game = CreatedGame | StartedGame | CompletedGame | ForfeitedGame;
106
- type CreatedGame = {
107
- readonly status: "created";
108
- readonly id: string;
109
- readonly createdAt: number;
110
- readonly expiresAt: number;
111
- readonly chatMessages: readonly ChatMessage[];
112
- readonly players: Player$1[];
113
- };
114
- type StartedGame = {
115
- readonly status: "started";
116
- readonly id: string;
117
- readonly createdAt: number;
118
- expiresAt: number;
119
- readonly chatMessages: readonly ChatMessage[];
120
- readonly players: Player$1[];
121
- canPlayAt: number;
122
- };
123
- type CompletedGame = {
124
- readonly status: "completed";
125
- readonly id: string;
126
- readonly createdAt: number;
127
- readonly expiresAt: number;
128
- readonly chatMessages: readonly ChatMessage[];
129
- readonly players: Player$1[];
130
- };
131
- type ForfeitedGame = {
132
- readonly status: "forfeited";
133
- readonly id: string;
134
- readonly createdAt: number;
135
- readonly expiresAt: number;
136
- readonly chatMessages: readonly ChatMessage[];
137
- readonly players: Player$1[];
138
- };
139
- //#endregion
140
- //#region src/game/types/ClientState.d.ts
141
- type ClientState = {
142
- readonly status: "created" | "started" | "completed" | "forfeited";
143
- readonly gameId: string;
144
- readonly playerId: string;
145
- readonly username: string;
146
- readonly players: readonly Player[];
147
- readonly expiresAt: number;
148
- readonly chatMessages: readonly ChatMessage[];
149
- readonly hand: readonly Card[];
150
- readonly canPlayAt: number | null;
151
- };
152
- type Player = {
153
- readonly username: string;
154
- readonly handSize: number;
155
- readonly drawPileSize: number;
156
- readonly sidePileSize: number;
157
- readonly centerPileTopCard: Card | null;
158
- };
159
- //#endregion
160
- //#region src/manager/Manager.d.ts
161
- type CreateGameResult = {
162
- readonly success: true;
163
- readonly gameId: string;
164
- readonly playerId: string;
165
- } | {
166
- readonly success: false;
167
- readonly error: "maxGamesReached";
168
- };
169
- type DrawCardResult = {
170
- readonly success: true;
171
- } | {
172
- readonly success: false;
173
- readonly error: "gameNotFound" | "playerNotFound" | "invalidStatus" | "canPlayAtNotReached" | "handFull" | "drawPileEmpty";
174
- };
175
- type GetClientStateAndClearEventsResult = {
176
- readonly success: true;
177
- readonly state: ClientState;
178
- } | {
179
- readonly success: false;
180
- readonly error: "gameNotFound" | "playerNotFound";
181
- };
182
- type GetEventsAndClearAcknowledgedResult = {
183
- readonly success: true;
184
- readonly events: readonly GameEvent[];
185
- } | {
186
- readonly success: false;
187
- readonly error: "gameNotFound" | "playerNotFound";
188
- };
189
- type GetJoinableGamesResult = {
190
- readonly games: readonly {
191
- readonly id: string;
192
- readonly numPlayers: number;
193
- }[];
194
- };
195
- type JoinGameResult = {
196
- readonly success: true;
197
- readonly playerId: string;
198
- } | {
199
- readonly success: false;
200
- readonly error: "gameNotFound" | "invalidStatus" | "maxPlayersReached" | "alreadyInGame";
201
- };
202
- type LeaveGameResult = {
203
- readonly success: true;
204
- } | {
205
- readonly success: false;
206
- readonly error: "gameNotFound" | "playerNotFound";
207
- };
208
- type PlayCardResult = {
209
- readonly success: true;
210
- } | {
211
- readonly success: false;
212
- readonly error: "gameNotFound" | "playerNotFound" | "invalidStatus" | "canPlayAtNotReached" | "cardNotFound" | "cardNotPlayable";
213
- };
214
- type ReportNoPlayableCardsResult = {
215
- readonly success: true;
216
- } | {
217
- readonly success: false;
218
- readonly error: "gameNotFound" | "playerNotFound" | "invalidStatus" | "canPlayAtNotReached" | "alreadyReported" | "hasPlayableCard" | "canDraw";
219
- };
220
- type SendChatResult = {
221
- readonly success: true;
222
- } | {
223
- readonly success: false;
224
- readonly error: "gameNotFound" | "playerNotFound";
225
- };
226
- type StartGameResult = {
227
- readonly success: true;
228
- } | {
229
- readonly success: false;
230
- readonly error: "gameNotFound" | "invalidStatus" | "playerNotFound" | "playerNotAdmin" | "minPlayersNotReached";
231
- };
232
- declare class Manager extends ManagerBase<Game> {
233
- createGame(userId: string, username: string): CreateGameResult;
234
- drawCard(gameId: string, playerId: string): DrawCardResult;
235
- getClientStateAndClearEvents(gameId: string, playerId: string): GetClientStateAndClearEventsResult;
236
- getEventsAndClearAcknowledged(gameId: string, playerId: string, lastReadId: string | null): GetEventsAndClearAcknowledgedResult;
237
- getJoinableGames(): GetJoinableGamesResult;
238
- joinGame(gameId: string, userId: string, username: string): JoinGameResult;
239
- leaveGame(gameId: string, playerId: string): LeaveGameResult;
240
- playCard(gameId: string, playerId: string, cardId: string, isForOtherPlayerPile: boolean): PlayCardResult;
241
- reportNoPlayableCards(gameId: string, playerId: string): ReportNoPlayableCardsResult;
242
- sendChat(gameId: string, playerId: string, text: string): SendChatResult;
243
- startGame(gameId: string, playerId: string): StartGameResult;
244
- }
245
- //#endregion
246
- export { GetJoinableGamesResult as a, Manager as c, SendChatResult as d, StartGameResult as f, Card as g, ChatMessage as h, GetEventsAndClearAcknowledgedResult as i, PlayCardResult as l, GameEvent as m, DrawCardResult as n, JoinGameResult as o, ClientState as p, GetClientStateAndClearEventsResult as r, LeaveGameResult as s, CreateGameResult as t, ReportNoPlayableCardsResult as u };
247
- //# sourceMappingURL=index-DlRknHKq.d.cts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-DlRknHKq.d.cts","names":[],"sources":["../src/game/types/Card.ts","../src/game/types/ChatMessage.ts","../src/game/types/GameEvent.ts","../src/game/types/Player.ts","../src/game/types/Game.ts","../src/game/types/ClientState.ts","../src/manager/Manager.ts"],"mappings":";;KAAY;WACD;WACA;WACA;;;;KCHC;WACD;WACA;WACA;;;;KCAC;WAEG;WACA;WACA;;WAGA;WACA;WACA;WACA,MAAM;;WAGN;WACA;WACA;WACA,MAAM;WACN;;WAGA;WACA;WACA,SAAS;;WAGT;WACA;WACA,MAAM;;WAGN;WACA;WACA;;WAGA;WACA;;WAGA;WACA;;WAGA;WACA;;WAGA;WACA;WACA,gBAAgB;;WAGhB;WACA;WACA;WACA,MAAM;;WAGN;WACA;WACA;WACA;;WAGA;WACA;WACA;;WAGA;WACA;WACA;WACA;;WAGA;WACA;WACA;;WAGA;WACA;WACA;;WAGA;WACA;WACA;WACA;;;;KCxFH;WACD;WACA;WACA;WACA,QAAQ;WACR,MAAM;WACN,UAAU;WACV,UAAU;WACV,YAAY;EACrB;;;;KCTU,OAAO,cAAc,cAAc,gBAAgB;KAEnD;WACD;WACA;WACA;WACA;WACA,uBAAuB;WACvB,SAAS;;KAGR;WACD;WACA;WACA;EACT;WACS,uBAAuB;WACvB,SAAS;EAClB;;KAGU;WACD;WACA;WACA;WACA;WACA,uBAAuB;WACvB,SAAS;;KAGR;WACD;WACA;WACA;WACA;WACA,uBAAuB;WACvB,SAAS;;;;KCpCR;WACD;WACA;WACA;WACA;WACA,kBAAkB;WAClB;WACA,uBAAuB;WACvB,eAAe;WACf;;KAGN;WACM;WACA;WACA;WACA;WACA,mBAAmB;;;;KCJlB;WAEG;WACA;WACA;;WAGA;WACA;;KAGH;WAEG;;WAGA;WACA;;KASH;WAEG;WACA,OAAO;;WAGP;WACA;;KAGH;WAEG;WACA,iBAAiB;;WAGjB;WACA;;KAGH;WACD;aACE;aACA;;;KAID;WAEG;WACA;;WAGA;WACA;;KAOH;WAEG;;WAGA;WACA;;KAGH;WAEG;;WAGA;WACA;;KASH;WAEG;;WAGA;WACA;;KAUH;WAEG;;WAGA;WACA;;KAGH;WAEG;;WAGA;WACA;;cAQF,gBAAgB,YAAY;EACvC,WAAW,gBAAgB,mBAAmB;EAS9C,SAAS,gBAAgB,mBAAmB;EAgB5C,6BACE,gBACA,mBACC;EAaH,8BACE,gBACA,kBACA,4BACC;EAaH,oBAAoB;EAWpB,SAAS,gBAAgB,gBAAgB,mBAAmB;EAgB5D,UAAU,gBAAgB,mBAAmB;EAiB7C,SACE,gBACA,kBACA,gBACA,gCACC;EAgBH,sBACE,gBACA,mBACC;EAgBH,SAAS,gBAAgB,kBAAkB,eAAe;EAa1D,UAAU,gBAAgB,mBAAmB"}
@@ -1,247 +0,0 @@
1
- import { ManagerBase } from "@hellacardgames/lib";
2
- //#region src/game/types/Card.d.ts
3
- type Card = {
4
- readonly id: string;
5
- readonly rank: 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14;
6
- readonly suite: "clubs" | "diamonds" | "hearts" | "spades";
7
- };
8
- //#endregion
9
- //#region src/game/types/ChatMessage.d.ts
10
- type ChatMessage = {
11
- readonly id: string;
12
- readonly username: string;
13
- readonly text: string;
14
- };
15
- //#endregion
16
- //#region src/game/types/GameEvent.d.ts
17
- type GameEvent = {
18
- readonly type: "canPlayAtUpdated";
19
- readonly id: string;
20
- readonly canPlayAt: number;
21
- } | {
22
- readonly type: "cardDrawnFromSidePileToCenterPile";
23
- readonly id: string;
24
- readonly username: string;
25
- readonly card: Card;
26
- } | {
27
- readonly type: "cardPlayed";
28
- readonly id: string;
29
- readonly username: string;
30
- readonly card: Card;
31
- readonly isForOtherPlayerPile: boolean;
32
- } | {
33
- readonly type: "chat";
34
- readonly id: string;
35
- readonly message: ChatMessage;
36
- } | {
37
- readonly type: "drewCard";
38
- readonly id: string;
39
- readonly card: Card;
40
- } | {
41
- readonly type: "expirationUpdated";
42
- readonly id: string;
43
- readonly expiresAt: number;
44
- } | {
45
- readonly type: "gameCompleted";
46
- readonly id: string;
47
- } | {
48
- readonly type: "gameForfeited";
49
- readonly id: string;
50
- } | {
51
- readonly type: "gameStarted";
52
- readonly id: string;
53
- } | {
54
- readonly type: "handInitialized";
55
- readonly id: string;
56
- readonly cards: readonly Card[];
57
- } | {
58
- readonly type: "playerCenterPileInitialized";
59
- readonly id: string;
60
- readonly username: string;
61
- readonly card: Card;
62
- } | {
63
- readonly type: "playerDrawPileInitialized";
64
- readonly id: string;
65
- readonly username: string;
66
- readonly numCards: number;
67
- } | {
68
- readonly type: "playerDrewCard";
69
- readonly id: string;
70
- readonly username: string;
71
- } | {
72
- readonly type: "playerHandInitialized";
73
- readonly id: string;
74
- readonly username: string;
75
- readonly numCards: number;
76
- } | {
77
- readonly type: "playerJoined";
78
- readonly id: string;
79
- readonly username: string;
80
- } | {
81
- readonly type: "playerLeft";
82
- readonly id: string;
83
- readonly username: string;
84
- } | {
85
- readonly type: "playerSidePileInitialized";
86
- readonly id: string;
87
- readonly username: string;
88
- readonly numCards: number;
89
- };
90
- //#endregion
91
- //#region src/game/types/Player.d.ts
92
- type Player$1 = {
93
- readonly id: string;
94
- readonly userId: string;
95
- readonly username: string;
96
- readonly events: GameEvent[];
97
- readonly hand: Card[];
98
- readonly drawPile: Card[];
99
- readonly sidePile: Card[];
100
- readonly centerPile: Card[];
101
- hasNoPlayableCards: boolean;
102
- };
103
- //#endregion
104
- //#region src/game/types/Game.d.ts
105
- type Game = CreatedGame | StartedGame | CompletedGame | ForfeitedGame;
106
- type CreatedGame = {
107
- readonly status: "created";
108
- readonly id: string;
109
- readonly createdAt: number;
110
- readonly expiresAt: number;
111
- readonly chatMessages: readonly ChatMessage[];
112
- readonly players: Player$1[];
113
- };
114
- type StartedGame = {
115
- readonly status: "started";
116
- readonly id: string;
117
- readonly createdAt: number;
118
- expiresAt: number;
119
- readonly chatMessages: readonly ChatMessage[];
120
- readonly players: Player$1[];
121
- canPlayAt: number;
122
- };
123
- type CompletedGame = {
124
- readonly status: "completed";
125
- readonly id: string;
126
- readonly createdAt: number;
127
- readonly expiresAt: number;
128
- readonly chatMessages: readonly ChatMessage[];
129
- readonly players: Player$1[];
130
- };
131
- type ForfeitedGame = {
132
- readonly status: "forfeited";
133
- readonly id: string;
134
- readonly createdAt: number;
135
- readonly expiresAt: number;
136
- readonly chatMessages: readonly ChatMessage[];
137
- readonly players: Player$1[];
138
- };
139
- //#endregion
140
- //#region src/game/types/ClientState.d.ts
141
- type ClientState = {
142
- readonly status: "created" | "started" | "completed" | "forfeited";
143
- readonly gameId: string;
144
- readonly playerId: string;
145
- readonly username: string;
146
- readonly players: readonly Player[];
147
- readonly expiresAt: number;
148
- readonly chatMessages: readonly ChatMessage[];
149
- readonly hand: readonly Card[];
150
- readonly canPlayAt: number | null;
151
- };
152
- type Player = {
153
- readonly username: string;
154
- readonly handSize: number;
155
- readonly drawPileSize: number;
156
- readonly sidePileSize: number;
157
- readonly centerPileTopCard: Card | null;
158
- };
159
- //#endregion
160
- //#region src/manager/Manager.d.ts
161
- type CreateGameResult = {
162
- readonly success: true;
163
- readonly gameId: string;
164
- readonly playerId: string;
165
- } | {
166
- readonly success: false;
167
- readonly error: "maxGamesReached";
168
- };
169
- type DrawCardResult = {
170
- readonly success: true;
171
- } | {
172
- readonly success: false;
173
- readonly error: "gameNotFound" | "playerNotFound" | "invalidStatus" | "canPlayAtNotReached" | "handFull" | "drawPileEmpty";
174
- };
175
- type GetClientStateAndClearEventsResult = {
176
- readonly success: true;
177
- readonly state: ClientState;
178
- } | {
179
- readonly success: false;
180
- readonly error: "gameNotFound" | "playerNotFound";
181
- };
182
- type GetEventsAndClearAcknowledgedResult = {
183
- readonly success: true;
184
- readonly events: readonly GameEvent[];
185
- } | {
186
- readonly success: false;
187
- readonly error: "gameNotFound" | "playerNotFound";
188
- };
189
- type GetJoinableGamesResult = {
190
- readonly games: readonly {
191
- readonly id: string;
192
- readonly numPlayers: number;
193
- }[];
194
- };
195
- type JoinGameResult = {
196
- readonly success: true;
197
- readonly playerId: string;
198
- } | {
199
- readonly success: false;
200
- readonly error: "gameNotFound" | "invalidStatus" | "maxPlayersReached" | "alreadyInGame";
201
- };
202
- type LeaveGameResult = {
203
- readonly success: true;
204
- } | {
205
- readonly success: false;
206
- readonly error: "gameNotFound" | "playerNotFound";
207
- };
208
- type PlayCardResult = {
209
- readonly success: true;
210
- } | {
211
- readonly success: false;
212
- readonly error: "gameNotFound" | "playerNotFound" | "invalidStatus" | "canPlayAtNotReached" | "cardNotFound" | "cardNotPlayable";
213
- };
214
- type ReportNoPlayableCardsResult = {
215
- readonly success: true;
216
- } | {
217
- readonly success: false;
218
- readonly error: "gameNotFound" | "playerNotFound" | "invalidStatus" | "canPlayAtNotReached" | "alreadyReported" | "hasPlayableCard" | "canDraw";
219
- };
220
- type SendChatResult = {
221
- readonly success: true;
222
- } | {
223
- readonly success: false;
224
- readonly error: "gameNotFound" | "playerNotFound";
225
- };
226
- type StartGameResult = {
227
- readonly success: true;
228
- } | {
229
- readonly success: false;
230
- readonly error: "gameNotFound" | "invalidStatus" | "playerNotFound" | "playerNotAdmin" | "minPlayersNotReached";
231
- };
232
- declare class Manager extends ManagerBase<Game> {
233
- createGame(userId: string, username: string): CreateGameResult;
234
- drawCard(gameId: string, playerId: string): DrawCardResult;
235
- getClientStateAndClearEvents(gameId: string, playerId: string): GetClientStateAndClearEventsResult;
236
- getEventsAndClearAcknowledged(gameId: string, playerId: string, lastReadId: string | null): GetEventsAndClearAcknowledgedResult;
237
- getJoinableGames(): GetJoinableGamesResult;
238
- joinGame(gameId: string, userId: string, username: string): JoinGameResult;
239
- leaveGame(gameId: string, playerId: string): LeaveGameResult;
240
- playCard(gameId: string, playerId: string, cardId: string, isForOtherPlayerPile: boolean): PlayCardResult;
241
- reportNoPlayableCards(gameId: string, playerId: string): ReportNoPlayableCardsResult;
242
- sendChat(gameId: string, playerId: string, text: string): SendChatResult;
243
- startGame(gameId: string, playerId: string): StartGameResult;
244
- }
245
- //#endregion
246
- export { GetJoinableGamesResult as a, Manager as c, SendChatResult as d, StartGameResult as f, Card as g, ChatMessage as h, GetEventsAndClearAcknowledgedResult as i, PlayCardResult as l, GameEvent as m, DrawCardResult as n, JoinGameResult as o, ClientState as p, GetClientStateAndClearEventsResult as r, LeaveGameResult as s, CreateGameResult as t, ReportNoPlayableCardsResult as u };
247
- //# sourceMappingURL=index-DlRknHKq.d.mts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-DlRknHKq.d.mts","names":[],"sources":["../src/game/types/Card.ts","../src/game/types/ChatMessage.ts","../src/game/types/GameEvent.ts","../src/game/types/Player.ts","../src/game/types/Game.ts","../src/game/types/ClientState.ts","../src/manager/Manager.ts"],"mappings":";;KAAY;WACD;WACA;WACA;;;;KCHC;WACD;WACA;WACA;;;;KCAC;WAEG;WACA;WACA;;WAGA;WACA;WACA;WACA,MAAM;;WAGN;WACA;WACA;WACA,MAAM;WACN;;WAGA;WACA;WACA,SAAS;;WAGT;WACA;WACA,MAAM;;WAGN;WACA;WACA;;WAGA;WACA;;WAGA;WACA;;WAGA;WACA;;WAGA;WACA;WACA,gBAAgB;;WAGhB;WACA;WACA;WACA,MAAM;;WAGN;WACA;WACA;WACA;;WAGA;WACA;WACA;;WAGA;WACA;WACA;WACA;;WAGA;WACA;WACA;;WAGA;WACA;WACA;;WAGA;WACA;WACA;WACA;;;;KCxFH;WACD;WACA;WACA;WACA,QAAQ;WACR,MAAM;WACN,UAAU;WACV,UAAU;WACV,YAAY;EACrB;;;;KCTU,OAAO,cAAc,cAAc,gBAAgB;KAEnD;WACD;WACA;WACA;WACA;WACA,uBAAuB;WACvB,SAAS;;KAGR;WACD;WACA;WACA;EACT;WACS,uBAAuB;WACvB,SAAS;EAClB;;KAGU;WACD;WACA;WACA;WACA;WACA,uBAAuB;WACvB,SAAS;;KAGR;WACD;WACA;WACA;WACA;WACA,uBAAuB;WACvB,SAAS;;;;KCpCR;WACD;WACA;WACA;WACA;WACA,kBAAkB;WAClB;WACA,uBAAuB;WACvB,eAAe;WACf;;KAGN;WACM;WACA;WACA;WACA;WACA,mBAAmB;;;;KCJlB;WAEG;WACA;WACA;;WAGA;WACA;;KAGH;WAEG;;WAGA;WACA;;KASH;WAEG;WACA,OAAO;;WAGP;WACA;;KAGH;WAEG;WACA,iBAAiB;;WAGjB;WACA;;KAGH;WACD;aACE;aACA;;;KAID;WAEG;WACA;;WAGA;WACA;;KAOH;WAEG;;WAGA;WACA;;KAGH;WAEG;;WAGA;WACA;;KASH;WAEG;;WAGA;WACA;;KAUH;WAEG;;WAGA;WACA;;KAGH;WAEG;;WAGA;WACA;;cAQF,gBAAgB,YAAY;EACvC,WAAW,gBAAgB,mBAAmB;EAS9C,SAAS,gBAAgB,mBAAmB;EAgB5C,6BACE,gBACA,mBACC;EAaH,8BACE,gBACA,kBACA,4BACC;EAaH,oBAAoB;EAWpB,SAAS,gBAAgB,gBAAgB,mBAAmB;EAgB5D,UAAU,gBAAgB,mBAAmB;EAiB7C,SACE,gBACA,kBACA,gBACA,gCACC;EAgBH,sBACE,gBACA,mBACC;EAgBH,SAAS,gBAAgB,kBAAkB,eAAe;EAa1D,UAAU,gBAAgB,mBAAmB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"manager-0r8lvLRR.cjs","names":["emitEvent","doGetEventsAndClearAcknowledged","addItemToCollection","emitEvent","ManagerBase"],"sources":["../src/game/constants.ts","../src/game/actions/createGame.ts","../src/game/lib/emitEvent.ts","../src/game/lib/emitEventToPlayer.ts","../src/game/actions/drawCard.ts","../src/game/actions/getClientStateAndClearEvents.ts","../src/game/actions/getEventsAndClearAcknowledged.ts","../src/game/actions/joinGame.ts","../src/game/actions/leaveGame.ts","../src/game/lib/isCardPlayable.ts","../src/game/lib/hasPlayableCard.ts","../src/game/actions/playCard.ts","../src/game/lib/shuffleCards.ts","../src/game/actions/reportNoPlayableCards.ts","../src/game/actions/sendChat.ts","../src/game/actions/startGame.ts","../src/manager/Manager.ts"],"sourcesContent":["import type { Card } from \"./types/Card.js\";\n\nexport const EXPIRY_EXTENSION_MS = 300000; // 5 minutes\nexport const MIN_PLAYERS = 2;\nexport const MAX_PLAYERS = 2;\nexport const MAX_HAND_SIZE = 5;\nexport const CAN_PLAY_AT_DELAY_MS = 3000;\n\nexport const CARDS: readonly Card[] = [\n { id: crypto.randomUUID(), rank: 2, suite: \"clubs\" },\n { id: crypto.randomUUID(), rank: 3, suite: \"clubs\" },\n { id: crypto.randomUUID(), rank: 4, suite: \"clubs\" },\n { id: crypto.randomUUID(), rank: 5, suite: \"clubs\" },\n { id: crypto.randomUUID(), rank: 6, suite: \"clubs\" },\n { id: crypto.randomUUID(), rank: 7, suite: \"clubs\" },\n { id: crypto.randomUUID(), rank: 8, suite: \"clubs\" },\n { id: crypto.randomUUID(), rank: 9, suite: \"clubs\" },\n { id: crypto.randomUUID(), rank: 10, suite: \"clubs\" },\n { id: crypto.randomUUID(), rank: 11, suite: \"clubs\" },\n { id: crypto.randomUUID(), rank: 12, suite: \"clubs\" },\n { id: crypto.randomUUID(), rank: 13, suite: \"clubs\" },\n { id: crypto.randomUUID(), rank: 14, suite: \"clubs\" },\n { id: crypto.randomUUID(), rank: 2, suite: \"diamonds\" },\n { id: crypto.randomUUID(), rank: 3, suite: \"diamonds\" },\n { id: crypto.randomUUID(), rank: 4, suite: \"diamonds\" },\n { id: crypto.randomUUID(), rank: 5, suite: \"diamonds\" },\n { id: crypto.randomUUID(), rank: 6, suite: \"diamonds\" },\n { id: crypto.randomUUID(), rank: 7, suite: \"diamonds\" },\n { id: crypto.randomUUID(), rank: 8, suite: \"diamonds\" },\n { id: crypto.randomUUID(), rank: 9, suite: \"diamonds\" },\n { id: crypto.randomUUID(), rank: 10, suite: \"diamonds\" },\n { id: crypto.randomUUID(), rank: 11, suite: \"diamonds\" },\n { id: crypto.randomUUID(), rank: 12, suite: \"diamonds\" },\n { id: crypto.randomUUID(), rank: 13, suite: \"diamonds\" },\n { id: crypto.randomUUID(), rank: 14, suite: \"diamonds\" },\n { id: crypto.randomUUID(), rank: 2, suite: \"hearts\" },\n { id: crypto.randomUUID(), rank: 3, suite: \"hearts\" },\n { id: crypto.randomUUID(), rank: 4, suite: \"hearts\" },\n { id: crypto.randomUUID(), rank: 5, suite: \"hearts\" },\n { id: crypto.randomUUID(), rank: 6, suite: \"hearts\" },\n { id: crypto.randomUUID(), rank: 7, suite: \"hearts\" },\n { id: crypto.randomUUID(), rank: 8, suite: \"hearts\" },\n { id: crypto.randomUUID(), rank: 9, suite: \"hearts\" },\n { id: crypto.randomUUID(), rank: 10, suite: \"hearts\" },\n { id: crypto.randomUUID(), rank: 11, suite: \"hearts\" },\n { id: crypto.randomUUID(), rank: 12, suite: \"hearts\" },\n { id: crypto.randomUUID(), rank: 13, suite: \"hearts\" },\n { id: crypto.randomUUID(), rank: 14, suite: \"hearts\" },\n { id: crypto.randomUUID(), rank: 2, suite: \"spades\" },\n { id: crypto.randomUUID(), rank: 3, suite: \"spades\" },\n { id: crypto.randomUUID(), rank: 4, suite: \"spades\" },\n { id: crypto.randomUUID(), rank: 5, suite: \"spades\" },\n { id: crypto.randomUUID(), rank: 6, suite: \"spades\" },\n { id: crypto.randomUUID(), rank: 7, suite: \"spades\" },\n { id: crypto.randomUUID(), rank: 8, suite: \"spades\" },\n { id: crypto.randomUUID(), rank: 9, suite: \"spades\" },\n { id: crypto.randomUUID(), rank: 10, suite: \"spades\" },\n { id: crypto.randomUUID(), rank: 11, suite: \"spades\" },\n { id: crypto.randomUUID(), rank: 12, suite: \"spades\" },\n { id: crypto.randomUUID(), rank: 13, suite: \"spades\" },\n { id: crypto.randomUUID(), rank: 14, suite: \"spades\" },\n];\n","import { EXPIRY_EXTENSION_MS } from \"../constants.js\";\nimport type { CreatedGame } from \"../types/Game.js\";\nimport type { Player } from \"../types/Player.js\";\n\ntype CreateGameResult = {\n readonly game: CreatedGame;\n readonly playerId: string;\n};\n\nexport function createGame(userId: string, username: string): CreateGameResult {\n const player: Player = {\n id: crypto.randomUUID(),\n userId,\n username,\n events: [],\n hand: [],\n drawPile: [],\n sidePile: [],\n centerPile: [],\n hasNoPlayableCards: false,\n };\n\n const createdAt = Date.now();\n\n const game: CreatedGame = {\n status: \"created\",\n id: crypto.randomUUID(),\n createdAt,\n expiresAt: createdAt + EXPIRY_EXTENSION_MS,\n chatMessages: [],\n players: [player],\n };\n\n return { game, playerId: player.id };\n}\n","type Game = {\n readonly players: {\n readonly events: { readonly id: string }[];\n }[];\n};\n\ntype OmitId<T> = T extends unknown ? Omit<T, \"id\"> : never;\n\nexport function emitEvent<T extends Game>(\n game: T,\n data: OmitId<T[\"players\"][number][\"events\"][number]>,\n): void {\n const event = { ...data, id: crypto.randomUUID() };\n for (const p of game.players) {\n p.events.push(event);\n }\n}\n","type Player = {\n readonly events: { readonly id: string }[];\n};\n\ntype OmitId<T> = T extends unknown ? Omit<T, \"id\"> : never;\n\nexport function emitEventToPlayer<T extends Player>(\n player: T,\n data: OmitId<T[\"events\"][number]>,\n): void {\n player.events.push({ ...data, id: crypto.randomUUID() });\n}\n","import { emitEvent } from \"../lib/emitEvent.js\";\nimport { emitEventToPlayer } from \"../lib/emitEventToPlayer.js\";\nimport { EXPIRY_EXTENSION_MS, MAX_HAND_SIZE } from \"../constants.js\";\nimport type { StartedGame } from \"../types/Game.js\";\n\ntype DrawCardResult =\n | {\n readonly success: true;\n readonly game: StartedGame;\n }\n | {\n readonly success: false;\n readonly error:\n \"playerNotFound\" | \"canPlayAtNotReached\" | \"handFull\" | \"drawPileEmpty\";\n };\n\nexport function drawCard(game: StartedGame, playerId: string): DrawCardResult {\n const player = game.players.find((p) => p.id === playerId);\n if (!player) {\n return { success: false, error: \"playerNotFound\" };\n }\n if (Date.now() < game.canPlayAt) {\n return { success: false, error: \"canPlayAtNotReached\" };\n }\n if (player.hand.length >= MAX_HAND_SIZE) {\n return { success: false, error: \"handFull\" };\n }\n if (player.drawPile.length === 0) {\n return { success: false, error: \"drawPileEmpty\" };\n }\n game.expiresAt = Date.now() + EXPIRY_EXTENSION_MS;\n emitEvent(game, { type: \"expirationUpdated\", expiresAt: game.expiresAt });\n const card = player.drawPile.pop()!;\n player.hand.push(card);\n emitEventToPlayer(player, { type: \"drewCard\", card });\n emitEvent(game, { type: \"playerDrewCard\", username: player.username });\n return { success: true, game };\n}\n","import type { ClientState } from \"../types/ClientState.js\";\nimport type { Game } from \"../types/Game.js\";\n\ntype GetClientStateAndClearEventsResult =\n | {\n readonly success: true;\n readonly state: ClientState;\n readonly game: Game;\n }\n | {\n readonly success: false;\n readonly error: \"playerNotFound\";\n };\n\nexport function getClientStateAndClearEvents(\n game: Game,\n playerId: string,\n): GetClientStateAndClearEventsResult {\n const player = game.players.find((p) => p.id === playerId);\n if (!player) {\n return { success: false, error: \"playerNotFound\" };\n }\n const state: ClientState = {\n status: game.status,\n gameId: game.id,\n playerId,\n username: player.username,\n players: game.players.map((p) => ({\n username: p.username,\n handSize: p.hand.length,\n drawPileSize: p.drawPile.length,\n sidePileSize: p.sidePile.length,\n centerPileTopCard: p.centerPile.length\n ? p.centerPile[p.centerPile.length - 1]!\n : null,\n })),\n expiresAt: game.expiresAt,\n chatMessages: game.chatMessages,\n hand: player.hand,\n canPlayAt: game.status === \"started\" ? game.canPlayAt : null,\n };\n player.events.length = 0;\n return { success: true, state, game };\n}\n","import { getEventsAndClearAcknowledged as doGetEventsAndClearAcknowledged } from \"@hellacardgames/lib\";\nimport type { Game } from \"../types/Game.js\";\nimport type { GameEvent } from \"../types/GameEvent.js\";\n\ntype GetEventsAndClearAcknowledgedResult =\n | {\n readonly success: true;\n readonly events: readonly GameEvent[];\n readonly game: Game;\n }\n | {\n readonly success: false;\n readonly error: \"playerNotFound\";\n };\n\nexport function getEventsAndClearAcknowledged(\n game: Game,\n playerId: string,\n lastReadId: string | null,\n): GetEventsAndClearAcknowledgedResult {\n const player = game.players.find((p) => p.id === playerId);\n if (!player) {\n return { success: false, error: \"playerNotFound\" };\n }\n\n const result = doGetEventsAndClearAcknowledged(game, player.id, lastReadId);\n\n return {\n success: true,\n events: result.events,\n game: result.game,\n };\n}\n","import { emitEvent } from \"../lib/emitEvent.js\";\nimport { MAX_PLAYERS } from \"../constants.js\";\nimport type { CreatedGame } from \"../types/Game.js\";\nimport type { Player } from \"../types/Player.js\";\n\ntype JoinGameResult =\n | {\n readonly success: true;\n readonly game: CreatedGame;\n readonly playerId: string;\n }\n | {\n readonly success: false;\n readonly error: \"maxPlayersReached\" | \"alreadyInGame\";\n };\n\nexport function joinGame(\n game: CreatedGame,\n userId: string,\n username: string,\n): JoinGameResult {\n if (game.players.length === MAX_PLAYERS) {\n return { success: false, error: \"maxPlayersReached\" };\n }\n if (game.players.find((p) => p.userId === userId)) {\n return { success: false, error: \"alreadyInGame\" };\n }\n const player: Player = {\n id: crypto.randomUUID(),\n userId,\n username,\n events: [],\n hand: [],\n drawPile: [],\n sidePile: [],\n centerPile: [],\n hasNoPlayableCards: false,\n };\n game.players.push(player);\n emitEvent(game, { type: \"playerJoined\", username });\n return { success: true, game, playerId: player.id };\n}\n","import { emitEvent } from \"../lib/emitEvent.js\";\nimport { EXPIRY_EXTENSION_MS, MIN_PLAYERS } from \"../constants.js\";\nimport type { Game } from \"../types/Game.js\";\n\ntype LeaveGameResult =\n | {\n readonly success: true;\n readonly game: Game;\n }\n | {\n readonly success: false;\n readonly error: \"playerNotFound\";\n };\n\nexport function leaveGame(game: Game, playerId: string): LeaveGameResult {\n const playerIndex = game.players.findIndex((p) => p.id === playerId);\n if (playerIndex === -1) {\n return { success: false, error: \"playerNotFound\" };\n }\n\n const player = game.players[playerIndex]!;\n emitEvent(game, { type: \"playerLeft\", username: player.username });\n\n game.players.splice(playerIndex, 1);\n\n if (game.status === \"started\" && game.players.length < MIN_PLAYERS) {\n const forfeitedGame: Game = {\n ...game,\n status: \"forfeited\",\n expiresAt: Date.now() + EXPIRY_EXTENSION_MS,\n };\n // this.games.set(game.id, forfeitedGame);\n emitEvent(forfeitedGame, { type: \"gameForfeited\" });\n emitEvent(forfeitedGame, {\n type: \"expirationUpdated\",\n expiresAt: forfeitedGame.expiresAt,\n });\n }\n return { success: true, game };\n}\n","import type { Card } from \"../types/Card.js\";\n\nexport function isCardPlayable(card: Card, targetPile: Card[]) {\n const targetCard = targetPile[targetPile.length - 1]!;\n const diff = Math.abs(card.rank - targetCard.rank) % 11;\n return diff === 1;\n}\n","import { isCardPlayable } from \"./isCardPlayable.js\";\nimport type { Game } from \"../types/Game.js\";\nimport type { Player } from \"../types/Player.js\";\n\nexport function hasPlayableCard(player: Player, game: Game) {\n const otherPlayer = game.players.find((p) => p !== player)!;\n const targetPile1 = player.centerPile;\n const targetPile2 = otherPlayer.centerPile;\n for (const card of player.hand) {\n if (\n isCardPlayable(card, targetPile1) ||\n isCardPlayable(card, targetPile2)\n ) {\n return true;\n }\n }\n return false;\n}\n","import { emitEvent } from \"../lib/emitEvent.js\";\nimport { EXPIRY_EXTENSION_MS } from \"../constants.js\";\nimport { hasPlayableCard } from \"../lib/hasPlayableCard.js\";\nimport { isCardPlayable } from \"../lib/isCardPlayable.js\";\nimport type { CompletedGame, StartedGame } from \"../types/Game.js\";\n\ntype PlayCardResult =\n | {\n readonly success: true;\n readonly game: StartedGame | CompletedGame;\n }\n | {\n readonly success: false;\n readonly error:\n | \"playerNotFound\"\n | \"canPlayAtNotReached\"\n | \"cardNotFound\"\n | \"cardNotPlayable\";\n };\n\nexport function playCard(\n game: StartedGame,\n playerId: string,\n cardId: string,\n isForOtherPlayerPile: boolean,\n): PlayCardResult {\n const player = game.players.find((p) => p.id === playerId);\n if (!player) {\n return { success: false, error: \"playerNotFound\" };\n }\n if (Date.now() < game.canPlayAt) {\n return { success: false, error: \"canPlayAtNotReached\" };\n }\n const cardIndex = player.hand.findIndex((c) => c.id === cardId);\n if (cardIndex === -1) {\n return { success: false, error: \"cardNotFound\" };\n }\n const otherPlayer = game.players.find((p) => p !== player)!;\n const targetPile = isForOtherPlayerPile\n ? otherPlayer.centerPile\n : player.centerPile;\n const card = player.hand[cardIndex]!;\n if (!isCardPlayable(card, targetPile)) {\n return { success: false, error: \"cardNotPlayable\" };\n }\n\n game.expiresAt = Date.now() + EXPIRY_EXTENSION_MS;\n emitEvent(game, { type: \"expirationUpdated\", expiresAt: game.expiresAt });\n\n player.hand.splice(cardIndex, 1);\n targetPile.push(card);\n emitEvent(game, {\n type: \"cardPlayed\",\n username: player.username,\n card,\n isForOtherPlayerPile,\n });\n\n if (otherPlayer.hasNoPlayableCards && hasPlayableCard(otherPlayer, game)) {\n otherPlayer.hasNoPlayableCards = false;\n }\n\n if (player.hand.length === 0 && player.drawPile.length === 0) {\n emitEvent(game, { type: \"gameCompleted\" });\n const completedGame: CompletedGame = {\n ...game,\n status: \"completed\",\n };\n return { success: true, game: completedGame };\n }\n\n return { success: true, game };\n}\n","type Card = { readonly id: string };\n\nexport function shuffleCards<T extends Card>(cards: T[]): void {\n for (let i = cards.length - 1; i > 0; i--) {\n const j = Math.floor(Math.random() * (i + 1));\n [cards[i], cards[j]] = [cards[j]!, cards[i]!];\n }\n}\n","import { emitEvent } from \"../lib/emitEvent.js\";\nimport { shuffleCards } from \"../lib/shuffleCards.js\";\nimport {\n CAN_PLAY_AT_DELAY_MS,\n EXPIRY_EXTENSION_MS,\n MAX_HAND_SIZE,\n} from \"../constants.js\";\nimport { hasPlayableCard } from \"../lib/hasPlayableCard.js\";\nimport type { StartedGame } from \"../types/Game.js\";\n\ntype ReportNoPlayableCardsResult =\n | {\n readonly success: true;\n readonly game: StartedGame;\n }\n | {\n readonly success: false;\n readonly error:\n | \"playerNotFound\"\n | \"canPlayAtNotReached\"\n | \"alreadyReported\"\n | \"hasPlayableCard\"\n | \"canDraw\";\n };\n\nexport function reportNoPlayableCards(\n game: StartedGame,\n playerId: string,\n): ReportNoPlayableCardsResult {\n const player = game.players.find((p) => p.id === playerId);\n if (!player) {\n return { success: false, error: \"playerNotFound\" };\n }\n if (Date.now() < game.canPlayAt) {\n return { success: false, error: \"canPlayAtNotReached\" };\n }\n if (player.hasNoPlayableCards) {\n return { success: false, error: \"alreadyReported\" };\n }\n if (hasPlayableCard(player, game)) {\n return { success: false, error: \"hasPlayableCard\" };\n }\n if (player.drawPile.length > 0 && player.hand.length < MAX_HAND_SIZE) {\n return { success: false, error: \"canDraw\" };\n }\n\n game.expiresAt = Date.now() + EXPIRY_EXTENSION_MS;\n emitEvent(game, { type: \"expirationUpdated\", expiresAt: game.expiresAt });\n\n player.hasNoPlayableCards = true;\n\n const otherPlayer = game.players.find((p) => p !== player)!;\n if (otherPlayer.hasNoPlayableCards) {\n if (player.sidePile.length === 0 && otherPlayer.sidePile.length === 0) {\n const cards = [...player.centerPile, ...otherPlayer.centerPile];\n shuffleCards(cards);\n player.sidePile.push(...cards.splice(0, 5));\n emitEvent(game, {\n type: \"playerSidePileInitialized\",\n username: player.username,\n numCards: player.sidePile.length,\n });\n player.centerPile.push(...cards.splice(0, 1));\n emitEvent(game, {\n type: \"playerCenterPileInitialized\",\n username: player.username,\n card: player.centerPile[player.centerPile.length - 1]!,\n });\n otherPlayer.centerPile.push(...cards.splice(0, 1));\n emitEvent(game, {\n type: \"playerCenterPileInitialized\",\n username: otherPlayer.username,\n card: otherPlayer.centerPile[otherPlayer.centerPile.length - 1]!,\n });\n otherPlayer.sidePile.push(...cards.splice(0, 5));\n emitEvent(game, {\n type: \"playerSidePileInitialized\",\n username: otherPlayer.username,\n numCards: otherPlayer.sidePile.length,\n });\n } else {\n const playerSidePileCard = player.sidePile.pop()!;\n player.centerPile.push(playerSidePileCard);\n emitEvent(game, {\n type: \"cardDrawnFromSidePileToCenterPile\",\n username: player.username,\n card: playerSidePileCard,\n });\n const otherPlayerSidePileCard = otherPlayer.sidePile.pop()!;\n otherPlayer.centerPile.push(otherPlayerSidePileCard);\n emitEvent(game, {\n type: \"cardDrawnFromSidePileToCenterPile\",\n username: otherPlayer.username,\n card: otherPlayerSidePileCard,\n });\n }\n player.hasNoPlayableCards = false;\n otherPlayer.hasNoPlayableCards = false;\n game.canPlayAt = Date.now() + CAN_PLAY_AT_DELAY_MS;\n emitEvent(game, {\n type: \"canPlayAtUpdated\",\n canPlayAt: game.canPlayAt,\n });\n }\n\n return { success: true, game };\n}\n","import { addItemToCollection, emitEvent } from \"@hellacardgames/lib\";\nimport type { ChatMessage } from \"../types/ChatMessage.js\";\nimport type { Game } from \"../types/Game.js\";\n\ntype SendChatResult =\n | {\n readonly success: true;\n readonly game: Game;\n }\n | {\n readonly success: false;\n readonly error: \"playerNotFound\";\n };\n\nexport function sendChat(\n game: Game,\n playerId: string,\n text: string,\n): SendChatResult {\n const player = game.players.find((p) => p.id === playerId);\n if (!player) {\n return { success: false, error: \"playerNotFound\" };\n }\n\n const message: ChatMessage = {\n id: crypto.randomUUID(),\n username: player.username,\n text,\n };\n\n game = {\n ...game,\n chatMessages: addItemToCollection(game.chatMessages, message),\n };\n\n game = emitEvent(game, { type: \"chat\", message });\n\n return { success: true, game };\n}\n","import { emitEvent } from \"../lib/emitEvent.js\";\nimport { emitEventToPlayer } from \"../lib/emitEventToPlayer.js\";\nimport { shuffleCards } from \"../lib/shuffleCards.js\";\nimport {\n CAN_PLAY_AT_DELAY_MS,\n CARDS,\n EXPIRY_EXTENSION_MS,\n MIN_PLAYERS,\n} from \"../constants.js\";\nimport type { CreatedGame, StartedGame } from \"../types/Game.js\";\n\ntype StartGameResult =\n | {\n readonly success: true;\n readonly game: StartedGame;\n }\n | {\n readonly success: false;\n readonly error:\n \"playerNotFound\" | \"playerNotAdmin\" | \"minPlayersNotReached\";\n };\n\nexport function startGame(\n game: CreatedGame,\n playerId: string,\n): StartGameResult {\n const player = game.players.find((p) => p.id === playerId);\n if (!player) {\n return { success: false, error: \"playerNotFound\" };\n }\n if (game.players.indexOf(player) !== 0) {\n return { success: false, error: \"playerNotAdmin\" };\n }\n if (game.players.length < MIN_PLAYERS) {\n return { success: false, error: \"minPlayersNotReached\" };\n }\n const otherPlayer = game.players[1]!;\n const cards = [...CARDS];\n shuffleCards(cards);\n\n player.sidePile.push(...cards.splice(0, 5));\n emitEvent(game, {\n type: \"playerSidePileInitialized\",\n username: player.username,\n numCards: player.sidePile.length,\n });\n\n player.centerPile.push(...cards.splice(0, 1));\n emitEvent(game, {\n type: \"playerCenterPileInitialized\",\n username: player.username,\n card: player.centerPile[player.centerPile.length - 1]!,\n });\n\n otherPlayer.centerPile.push(...cards.splice(0, 1));\n emitEvent(game, {\n type: \"playerCenterPileInitialized\",\n username: otherPlayer.username,\n card: otherPlayer.centerPile[otherPlayer.centerPile.length - 1]!,\n });\n\n otherPlayer.sidePile.push(...cards.splice(0, 5));\n emitEvent(game, {\n type: \"playerSidePileInitialized\",\n username: otherPlayer.username,\n numCards: otherPlayer.sidePile.length,\n });\n\n player.drawPile.push(...cards.splice(0, 15));\n emitEvent(game, {\n type: \"playerDrawPileInitialized\",\n username: player.username,\n numCards: player.drawPile.length,\n });\n\n player.hand.push(...cards.splice(0, 5));\n emitEventToPlayer(player, { type: \"handInitialized\", cards: player.hand });\n emitEvent(game, {\n type: \"playerHandInitialized\",\n username: player.username,\n numCards: player.hand.length,\n });\n\n otherPlayer.drawPile.push(...cards.splice(0, 15));\n emitEvent(game, {\n type: \"playerDrawPileInitialized\",\n username: otherPlayer.username,\n numCards: otherPlayer.drawPile.length,\n });\n\n otherPlayer.hand.push(...cards.splice(0, 5));\n emitEventToPlayer(otherPlayer, {\n type: \"handInitialized\",\n cards: otherPlayer.hand,\n });\n emitEvent(game, {\n type: \"playerHandInitialized\",\n username: otherPlayer.username,\n numCards: otherPlayer.hand.length,\n });\n\n const startedGame: StartedGame = {\n ...game,\n status: \"started\",\n expiresAt: Date.now() + EXPIRY_EXTENSION_MS,\n canPlayAt: Date.now() + CAN_PLAY_AT_DELAY_MS,\n };\n // this.games.set(game.id, startedGame);\n emitEvent(startedGame, { type: \"gameStarted\" });\n emitEvent(startedGame, {\n type: \"expirationUpdated\",\n expiresAt: startedGame.expiresAt,\n });\n emitEvent(startedGame, {\n type: \"canPlayAtUpdated\",\n canPlayAt: startedGame.canPlayAt,\n });\n return { success: true, game: startedGame };\n}\n","import { ManagerBase } from \"@hellacardgames/lib\";\nimport {\n createGame,\n drawCard,\n getClientStateAndClearEvents,\n getEventsAndClearAcknowledged,\n joinGame,\n leaveGame,\n MAX_PLAYERS,\n playCard,\n reportNoPlayableCards,\n sendChat,\n startGame,\n} from \"../game/index.js\";\nimport type { ClientState, Game, GameEvent } from \"../game/index.js\";\n\nexport type CreateGameResult =\n | {\n readonly success: true;\n readonly gameId: string;\n readonly playerId: string;\n }\n | {\n readonly success: false;\n readonly error: \"maxGamesReached\";\n };\n\nexport type DrawCardResult =\n | {\n readonly success: true;\n }\n | {\n readonly success: false;\n readonly error:\n | \"gameNotFound\"\n | \"playerNotFound\"\n | \"invalidStatus\"\n | \"canPlayAtNotReached\"\n | \"handFull\"\n | \"drawPileEmpty\";\n };\n\nexport type GetClientStateAndClearEventsResult =\n | {\n readonly success: true;\n readonly state: ClientState;\n }\n | {\n readonly success: false;\n readonly error: \"gameNotFound\" | \"playerNotFound\";\n };\n\nexport type GetEventsAndClearAcknowledgedResult =\n | {\n readonly success: true;\n readonly events: readonly GameEvent[];\n }\n | {\n readonly success: false;\n readonly error: \"gameNotFound\" | \"playerNotFound\";\n };\n\nexport type GetJoinableGamesResult = {\n readonly games: readonly {\n readonly id: string;\n readonly numPlayers: number;\n }[];\n};\n\nexport type JoinGameResult =\n | {\n readonly success: true;\n readonly playerId: string;\n }\n | {\n readonly success: false;\n readonly error:\n | \"gameNotFound\"\n | \"invalidStatus\"\n | \"maxPlayersReached\"\n | \"alreadyInGame\";\n };\n\nexport type LeaveGameResult =\n | {\n readonly success: true;\n }\n | {\n readonly success: false;\n readonly error: \"gameNotFound\" | \"playerNotFound\";\n };\n\nexport type PlayCardResult =\n | {\n readonly success: true;\n }\n | {\n readonly success: false;\n readonly error:\n | \"gameNotFound\"\n | \"playerNotFound\"\n | \"invalidStatus\"\n | \"canPlayAtNotReached\"\n | \"cardNotFound\"\n | \"cardNotPlayable\";\n };\n\nexport type ReportNoPlayableCardsResult =\n | {\n readonly success: true;\n }\n | {\n readonly success: false;\n readonly error:\n | \"gameNotFound\"\n | \"playerNotFound\"\n | \"invalidStatus\"\n | \"canPlayAtNotReached\"\n | \"alreadyReported\"\n | \"hasPlayableCard\"\n | \"canDraw\";\n };\n\nexport type SendChatResult =\n | {\n readonly success: true;\n }\n | {\n readonly success: false;\n readonly error: \"gameNotFound\" | \"playerNotFound\";\n };\n\nexport type StartGameResult =\n | {\n readonly success: true;\n }\n | {\n readonly success: false;\n readonly error:\n | \"gameNotFound\"\n | \"invalidStatus\"\n | \"playerNotFound\"\n | \"playerNotAdmin\"\n | \"minPlayersNotReached\";\n };\n\nexport class Manager extends ManagerBase<Game> {\n createGame(userId: string, username: string): CreateGameResult {\n if (this.games.size === this.maxGames) {\n return { success: false, error: \"maxGamesReached\" };\n }\n const result = createGame(userId, username);\n this.games.set(result.game.id, result.game);\n return { success: true, gameId: result.game.id, playerId: result.playerId };\n }\n\n drawCard(gameId: string, playerId: string): DrawCardResult {\n const game = this.games.get(gameId);\n if (!game) {\n return { success: false, error: \"gameNotFound\" };\n }\n if (game.status !== \"started\") {\n return { success: false, error: \"invalidStatus\" };\n }\n const result = drawCard(game, playerId);\n if (!result.success) {\n return result;\n }\n this.games.set(gameId, result.game);\n return { success: true };\n }\n\n getClientStateAndClearEvents(\n gameId: string,\n playerId: string,\n ): GetClientStateAndClearEventsResult {\n const game = this.games.get(gameId);\n if (!game) {\n return { success: false, error: \"gameNotFound\" };\n }\n const result = getClientStateAndClearEvents(game, playerId);\n if (!result.success) {\n return result;\n }\n this.games.set(gameId, result.game);\n return { success: true, state: result.state };\n }\n\n getEventsAndClearAcknowledged(\n gameId: string,\n playerId: string,\n lastReadId: string | null,\n ): GetEventsAndClearAcknowledgedResult {\n const game = this.games.get(gameId);\n if (!game) {\n return { success: false, error: \"gameNotFound\" };\n }\n const result = getEventsAndClearAcknowledged(game, playerId, lastReadId);\n if (!result.success) {\n return result;\n }\n this.games.set(gameId, result.game);\n return { success: true, events: result.events };\n }\n\n getJoinableGames(): GetJoinableGamesResult {\n return {\n games: Array.from(this.games.values())\n .filter((g) => g.status === \"created\" && g.players.length < MAX_PLAYERS)\n .map((g) => ({\n id: g.id,\n numPlayers: g.players.length,\n })),\n };\n }\n\n joinGame(gameId: string, userId: string, username: string): JoinGameResult {\n const game = this.games.get(gameId);\n if (!game) {\n return { success: false, error: \"gameNotFound\" };\n }\n if (game.status !== \"created\") {\n return { success: false, error: \"invalidStatus\" };\n }\n const result = joinGame(game, userId, username);\n if (!result.success) {\n return result;\n }\n this.games.set(gameId, result.game);\n return { success: true, playerId: result.playerId };\n }\n\n leaveGame(gameId: string, playerId: string): LeaveGameResult {\n const game = this.games.get(gameId);\n if (!game) {\n return { success: false, error: \"gameNotFound\" };\n }\n const result = leaveGame(game, playerId);\n if (!result.success) {\n return result;\n }\n if (result.game.players.length > 0) {\n this.games.set(gameId, result.game);\n } else {\n this.games.delete(gameId);\n }\n return { success: true };\n }\n\n playCard(\n gameId: string,\n playerId: string,\n cardId: string,\n isForOtherPlayerPile: boolean,\n ): PlayCardResult {\n const game = this.games.get(gameId);\n if (!game) {\n return { success: false, error: \"gameNotFound\" };\n }\n if (game.status !== \"started\") {\n return { success: false, error: \"invalidStatus\" };\n }\n const result = playCard(game, playerId, cardId, isForOtherPlayerPile);\n if (!result.success) {\n return result;\n }\n this.games.set(gameId, result.game);\n return { success: true };\n }\n\n reportNoPlayableCards(\n gameId: string,\n playerId: string,\n ): ReportNoPlayableCardsResult {\n const game = this.games.get(gameId);\n if (!game) {\n return { success: false, error: \"gameNotFound\" };\n }\n if (game.status !== \"started\") {\n return { success: false, error: \"invalidStatus\" };\n }\n const result = reportNoPlayableCards(game, playerId);\n if (!result.success) {\n return result;\n }\n this.games.set(gameId, result.game);\n return { success: true };\n }\n\n sendChat(gameId: string, playerId: string, text: string): SendChatResult {\n const game = this.games.get(gameId);\n if (!game) {\n return { success: false, error: \"gameNotFound\" };\n }\n const result = sendChat(game, playerId, text);\n if (!result.success) {\n return result;\n }\n this.games.set(gameId, result.game);\n return { success: true };\n }\n\n startGame(gameId: string, playerId: string): StartGameResult {\n const game = this.games.get(gameId);\n if (!game) {\n return { success: false, error: \"gameNotFound\" };\n }\n if (game.status !== \"created\") {\n return { success: false, error: \"invalidStatus\" };\n }\n const result = startGame(game, playerId);\n if (!result.success) {\n return result;\n }\n this.games.set(gameId, result.game);\n return { success: true };\n }\n}\n"],"mappings":"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"}