@hellacardgames/speed 0.5.1 → 0.5.3
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.
- package/dist/client/index.cjs.map +1 -1
- package/dist/client/index.d.cts +2 -3
- package/dist/client/index.d.cts.map +1 -1
- package/dist/client/index.d.mts +2 -3
- package/dist/client/index.d.mts.map +1 -1
- package/dist/client/index.mjs.map +1 -1
- package/dist/index-BilCO_4a.d.cts +216 -0
- package/dist/index-BilCO_4a.d.cts.map +1 -0
- package/dist/index-BilCO_4a.d.mts +216 -0
- package/dist/index-BilCO_4a.d.mts.map +1 -0
- package/dist/{startGame-5InkAgEp.d.cts → index-DSPZZlhq.d.cts} +39 -4
- package/dist/index-DSPZZlhq.d.cts.map +1 -0
- package/dist/{startGame-ayp8a-Cl.d.mts → index-S-oO1z9X.d.mts} +39 -4
- package/dist/index-S-oO1z9X.d.mts.map +1 -0
- package/dist/manager/index.cjs +12 -32
- package/dist/manager/index.d.cts +2 -109
- package/dist/manager/index.d.mts +2 -109
- package/dist/manager/index.mjs +1 -21
- package/dist/{startGame-BC9XfFzG.mjs → manager-CPmezdJa.mjs} +21 -2
- package/dist/manager-CPmezdJa.mjs.map +1 -0
- package/dist/{startGame-Bhk__XWk.cjs → manager-DErQ_XUq.cjs} +20 -19
- package/dist/manager-DErQ_XUq.cjs.map +1 -0
- package/dist/server/index.cjs +12 -12
- package/dist/server/index.cjs.map +1 -1
- package/dist/server/index.d.cts +3 -40
- package/dist/server/index.d.mts +3 -40
- package/dist/server/index.mjs +1 -1
- package/dist/server/index.mjs.map +1 -1
- package/package.json +2 -2
- package/dist/GameEvent-DDQ4jXxt.d.cts +0 -111
- package/dist/GameEvent-DDQ4jXxt.d.cts.map +0 -1
- package/dist/GameEvent-DDQ4jXxt.d.mts +0 -111
- package/dist/GameEvent-DDQ4jXxt.d.mts.map +0 -1
- package/dist/manager/index.cjs.map +0 -1
- package/dist/manager/index.d.cts.map +0 -1
- package/dist/manager/index.d.mts.map +0 -1
- package/dist/manager/index.mjs.map +0 -1
- package/dist/server/index.d.cts.map +0 -1
- package/dist/server/index.d.mts.map +0 -1
- package/dist/startGame-5InkAgEp.d.cts.map +0 -1
- package/dist/startGame-BC9XfFzG.mjs.map +0 -1
- package/dist/startGame-Bhk__XWk.cjs.map +0 -1
- package/dist/startGame-ayp8a-Cl.d.mts.map +0 -1
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { d as ClientState, l as GameEvent } from "./index-BilCO_4a.mjs";
|
|
3
2
|
//#region src/server/actions/createGame.d.ts
|
|
4
3
|
type CreateGameResult = {
|
|
5
4
|
readonly success: true;
|
|
@@ -104,5 +103,41 @@ type StartGameResult = {
|
|
|
104
103
|
};
|
|
105
104
|
declare function startGame(input: unknown): StartGameResult;
|
|
106
105
|
//#endregion
|
|
107
|
-
|
|
108
|
-
|
|
106
|
+
//#region src/server/index.d.ts
|
|
107
|
+
declare const actions: readonly [{
|
|
108
|
+
readonly path: "/createGame";
|
|
109
|
+
readonly action: typeof createGame;
|
|
110
|
+
}, {
|
|
111
|
+
readonly path: "/drawCard";
|
|
112
|
+
readonly action: typeof drawCard;
|
|
113
|
+
}, {
|
|
114
|
+
readonly path: "/getClientStateAndClearEvents";
|
|
115
|
+
readonly action: typeof getClientStateAndClearEvents;
|
|
116
|
+
}, {
|
|
117
|
+
readonly path: "/getEventsAndClearAcknowledged";
|
|
118
|
+
readonly action: typeof getEventsAndClearAcknowledged;
|
|
119
|
+
}, {
|
|
120
|
+
readonly path: "/getJoinableGames";
|
|
121
|
+
readonly action: typeof getJoinableGames;
|
|
122
|
+
}, {
|
|
123
|
+
readonly path: "/joinGame";
|
|
124
|
+
readonly action: typeof joinGame;
|
|
125
|
+
}, {
|
|
126
|
+
readonly path: "/leaveGame";
|
|
127
|
+
readonly action: typeof leaveGame;
|
|
128
|
+
}, {
|
|
129
|
+
readonly path: "/playCard";
|
|
130
|
+
readonly action: typeof playCard;
|
|
131
|
+
}, {
|
|
132
|
+
readonly path: "/reportNoPlayableCards";
|
|
133
|
+
readonly action: typeof reportNoPlayableCards;
|
|
134
|
+
}, {
|
|
135
|
+
readonly path: "/sendChat";
|
|
136
|
+
readonly action: typeof sendChat;
|
|
137
|
+
}, {
|
|
138
|
+
readonly path: "/startGame";
|
|
139
|
+
readonly action: typeof startGame;
|
|
140
|
+
}];
|
|
141
|
+
//#endregion
|
|
142
|
+
export { PlayCardResult as a, GetJoinableGamesResult as c, DrawCardResult as d, CreateGameResult as f, ReportNoPlayableCardsResult as i, GetEventsAndClearAcknowledgedResult as l, StartGameResult as n, LeaveGameResult as o, SendChatResult as r, JoinGameResult as s, actions as t, GetClientStateAndClearEventsResult as u };
|
|
143
|
+
//# sourceMappingURL=index-S-oO1z9X.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-S-oO1z9X.d.mts","names":[],"sources":["../src/server/actions/createGame.ts","../src/server/actions/drawCard.ts","../src/server/actions/getClientStateAndClearEvents.ts","../src/server/actions/getEventsAndClearAcknowledged.ts","../src/server/actions/getJoinableGames.ts","../src/server/actions/joinGame.ts","../src/server/actions/leaveGame.ts","../src/server/actions/playCard.ts","../src/server/actions/reportNoPlayableCards.ts","../src/server/actions/sendChat.ts","../src/server/actions/startGame.ts","../src/server/index.ts"],"mappings":";;KAEY;WAEG;WACA;WACA;;WAGA;WACA;;iBAGC,WAAW,gBAAgB,mBAAmB;;;KCVlD;WAEG;;WAGA;WACA;;iBAiBC,SAAS,iBAAiB;;;KCtB9B;WAEG;WACA,OAAO;;WAGP;WACA;;iBAUC,6BACd,iBACC;;;KCnBS;WAEG;WACA,iBAAiB;;WAGjB;WACA;;iBAcC,8BACd,iBACC;;;KCzBS;WACD;aACE;aACA;;;iBAIG,oBAAoB;;;KCNxB;WAEG;WACA;;WAGA;WACA;;iBAcC,SACd,gBACA,gBACA,mBACC;;;KCzBS;WAEG;;WAGA;WACA;;iBAUC,UAAU,iBAAiB;;;KChB/B;WAEG;;WAGA;WACA;;iBAsBC,SAAS,iBAAiB;;;KC5B9B;WAEG;;WAGA;WACA;;iBAkBC,sBACd,iBACC;;;KC1BS;WAEG;;WAGA;WACA;;iBAWC,SAAS,iBAAiB;;;KCjB9B;WAEG;;WAGA;WACA;;iBAgBC,UAAU,iBAAiB;;;cCM9B"}
|
package/dist/manager/index.cjs
CHANGED
|
@@ -1,33 +1,13 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
};
|
|
17
|
-
//#endregion
|
|
18
|
-
//#region src/manager/index.ts
|
|
19
|
-
new Watchdog().start();
|
|
20
|
-
//#endregion
|
|
21
|
-
exports.createGame = require_startGame.createGame;
|
|
22
|
-
exports.drawCard = require_startGame.drawCard;
|
|
23
|
-
exports.getClientStateAndClearEvents = require_startGame.getClientStateAndClearEvents;
|
|
24
|
-
exports.getEventsAndClearAcknowledged = require_startGame.getEventsAndClearAcknowledged;
|
|
25
|
-
exports.getJoinableGames = require_startGame.getJoinableGames;
|
|
26
|
-
exports.joinGame = require_startGame.joinGame;
|
|
27
|
-
exports.leaveGame = require_startGame.leaveGame;
|
|
28
|
-
exports.playCard = require_startGame.playCard;
|
|
29
|
-
exports.reportNoPlayableCards = require_startGame.reportNoPlayableCards;
|
|
30
|
-
exports.sendChat = require_startGame.sendChat;
|
|
31
|
-
exports.startGame = require_startGame.startGame;
|
|
32
|
-
|
|
33
|
-
//# sourceMappingURL=index.cjs.map
|
|
2
|
+
const require_manager = require("../manager-DErQ_XUq.cjs");
|
|
3
|
+
exports.createGame = require_manager.createGame;
|
|
4
|
+
exports.drawCard = require_manager.drawCard;
|
|
5
|
+
exports.getClientStateAndClearEvents = require_manager.getClientStateAndClearEvents;
|
|
6
|
+
exports.getEventsAndClearAcknowledged = require_manager.getEventsAndClearAcknowledged;
|
|
7
|
+
exports.getJoinableGames = require_manager.getJoinableGames;
|
|
8
|
+
exports.joinGame = require_manager.joinGame;
|
|
9
|
+
exports.leaveGame = require_manager.leaveGame;
|
|
10
|
+
exports.playCard = require_manager.playCard;
|
|
11
|
+
exports.reportNoPlayableCards = require_manager.reportNoPlayableCards;
|
|
12
|
+
exports.sendChat = require_manager.sendChat;
|
|
13
|
+
exports.startGame = require_manager.startGame;
|
package/dist/manager/index.d.cts
CHANGED
|
@@ -1,109 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
//#region src/manager/actions/createGame.d.ts
|
|
4
|
-
type CreateGameResult = {
|
|
5
|
-
readonly success: true;
|
|
6
|
-
readonly gameId: string;
|
|
7
|
-
readonly playerId: string;
|
|
8
|
-
} | {
|
|
9
|
-
readonly success: false;
|
|
10
|
-
readonly error: "maxGamesReached";
|
|
11
|
-
};
|
|
12
|
-
declare function createGame(userId: string, username: string): CreateGameResult;
|
|
13
|
-
//#endregion
|
|
14
|
-
//#region src/manager/actions/drawCard.d.ts
|
|
15
|
-
type DrawCardResult = {
|
|
16
|
-
readonly success: true;
|
|
17
|
-
} | {
|
|
18
|
-
readonly success: false;
|
|
19
|
-
readonly error: "gameNotFound" | "playerNotFound" | "invalidStatus" | "canPlayAtNotReached" | "handFull" | "drawPileEmpty";
|
|
20
|
-
};
|
|
21
|
-
declare function drawCard(gameId: string, playerId: string): DrawCardResult;
|
|
22
|
-
//#endregion
|
|
23
|
-
//#region src/manager/actions/getClientStateAndClearEvents.d.ts
|
|
24
|
-
type GetClientStateAndClearEventsResult = {
|
|
25
|
-
readonly success: true;
|
|
26
|
-
readonly state: ClientState;
|
|
27
|
-
} | {
|
|
28
|
-
readonly success: false;
|
|
29
|
-
readonly error: "gameNotFound" | "playerNotFound";
|
|
30
|
-
};
|
|
31
|
-
declare function getClientStateAndClearEvents(gameId: string, playerId: string): GetClientStateAndClearEventsResult;
|
|
32
|
-
//#endregion
|
|
33
|
-
//#region src/manager/actions/getEventsAndClearAcknowledged.d.ts
|
|
34
|
-
type GetEventsAndClearAcknowledgedResult = {
|
|
35
|
-
readonly success: true;
|
|
36
|
-
readonly events: readonly GameEvent[];
|
|
37
|
-
} | {
|
|
38
|
-
readonly success: false;
|
|
39
|
-
readonly error: "gameNotFound" | "playerNotFound";
|
|
40
|
-
};
|
|
41
|
-
declare function getEventsAndClearAcknowledged(gameId: string, playerId: string, lastReadId: string | null): GetEventsAndClearAcknowledgedResult;
|
|
42
|
-
//#endregion
|
|
43
|
-
//#region src/manager/actions/getJoinableGames.d.ts
|
|
44
|
-
type GetJoinableGamesResult = {
|
|
45
|
-
readonly success: true;
|
|
46
|
-
readonly games: readonly {
|
|
47
|
-
readonly id: string;
|
|
48
|
-
readonly numPlayers: number;
|
|
49
|
-
}[];
|
|
50
|
-
};
|
|
51
|
-
declare function getJoinableGames(): GetJoinableGamesResult;
|
|
52
|
-
//#endregion
|
|
53
|
-
//#region src/manager/actions/joinGame.d.ts
|
|
54
|
-
type JoinGameResult = {
|
|
55
|
-
readonly success: true;
|
|
56
|
-
readonly playerId: string;
|
|
57
|
-
} | {
|
|
58
|
-
readonly success: false;
|
|
59
|
-
readonly error: "gameNotFound" | "invalidStatus" | "maxPlayersReached" | "alreadyInGame";
|
|
60
|
-
};
|
|
61
|
-
declare function joinGame(gameId: string, userId: string, username: string): JoinGameResult;
|
|
62
|
-
//#endregion
|
|
63
|
-
//#region src/manager/actions/leaveGame.d.ts
|
|
64
|
-
type LeaveGameResult = {
|
|
65
|
-
readonly success: true;
|
|
66
|
-
} | {
|
|
67
|
-
readonly success: false;
|
|
68
|
-
readonly error: "gameNotFound" | "playerNotFound";
|
|
69
|
-
};
|
|
70
|
-
declare function leaveGame(gameId: string, playerId: string): LeaveGameResult;
|
|
71
|
-
//#endregion
|
|
72
|
-
//#region src/manager/actions/playCard.d.ts
|
|
73
|
-
type PlayCardResult = {
|
|
74
|
-
readonly success: true;
|
|
75
|
-
} | {
|
|
76
|
-
readonly success: false;
|
|
77
|
-
readonly error: "gameNotFound" | "playerNotFound" | "invalidStatus" | "canPlayAtNotReached" | "cardNotFound" | "cardNotPlayable";
|
|
78
|
-
};
|
|
79
|
-
declare function playCard(gameId: string, playerId: string, cardId: string, isForOtherPlayerPile: boolean): PlayCardResult;
|
|
80
|
-
//#endregion
|
|
81
|
-
//#region src/manager/actions/reportNoPlayableCards.d.ts
|
|
82
|
-
type ReportNoPlayableCardsResult = {
|
|
83
|
-
readonly success: true;
|
|
84
|
-
} | {
|
|
85
|
-
readonly success: false;
|
|
86
|
-
readonly error: "gameNotFound" | "playerNotFound" | "invalidStatus" | "canPlayAtNotReached" | "alreadyReported" | "hasPlayableCard" | "canDraw";
|
|
87
|
-
};
|
|
88
|
-
declare function reportNoPlayableCards(gameId: string, playerId: string): ReportNoPlayableCardsResult;
|
|
89
|
-
//#endregion
|
|
90
|
-
//#region src/manager/actions/sendChat.d.ts
|
|
91
|
-
type SendChatResult = {
|
|
92
|
-
readonly success: true;
|
|
93
|
-
} | {
|
|
94
|
-
readonly success: false;
|
|
95
|
-
readonly error: "gameNotFound" | "playerNotFound";
|
|
96
|
-
};
|
|
97
|
-
declare function sendChat(gameId: string, playerId: string, text: string): SendChatResult;
|
|
98
|
-
//#endregion
|
|
99
|
-
//#region src/manager/actions/startGame.d.ts
|
|
100
|
-
type StartGameResult = {
|
|
101
|
-
readonly success: true;
|
|
102
|
-
} | {
|
|
103
|
-
readonly success: false;
|
|
104
|
-
readonly error: "gameNotFound" | "playerNotFound" | "invalidStatus" | "playerNotAdmin" | "minPlayersNotReached";
|
|
105
|
-
};
|
|
106
|
-
declare function startGame(gameId: string, playerId: string): StartGameResult;
|
|
107
|
-
//#endregion
|
|
108
|
-
export { createGame, drawCard, getClientStateAndClearEvents, getEventsAndClearAcknowledged, getJoinableGames, joinGame, leaveGame, playCard, reportNoPlayableCards, sendChat, startGame };
|
|
109
|
-
//# sourceMappingURL=index.d.cts.map
|
|
1
|
+
import { a as leaveGame, c as getEventsAndClearAcknowledged, d as ClientState, f as ChatMessage, h as createGame, i as playCard, l as GameEvent, m as drawCard, n as sendChat, o as joinGame, p as Card, r as reportNoPlayableCards, s as getJoinableGames, t as startGame, u as getClientStateAndClearEvents } from "../index-BilCO_4a.cjs";
|
|
2
|
+
export { type Card, type ChatMessage, type ClientState, type GameEvent, createGame, drawCard, getClientStateAndClearEvents, getEventsAndClearAcknowledged, getJoinableGames, joinGame, leaveGame, playCard, reportNoPlayableCards, sendChat, startGame };
|
package/dist/manager/index.d.mts
CHANGED
|
@@ -1,109 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
//#region src/manager/actions/createGame.d.ts
|
|
4
|
-
type CreateGameResult = {
|
|
5
|
-
readonly success: true;
|
|
6
|
-
readonly gameId: string;
|
|
7
|
-
readonly playerId: string;
|
|
8
|
-
} | {
|
|
9
|
-
readonly success: false;
|
|
10
|
-
readonly error: "maxGamesReached";
|
|
11
|
-
};
|
|
12
|
-
declare function createGame(userId: string, username: string): CreateGameResult;
|
|
13
|
-
//#endregion
|
|
14
|
-
//#region src/manager/actions/drawCard.d.ts
|
|
15
|
-
type DrawCardResult = {
|
|
16
|
-
readonly success: true;
|
|
17
|
-
} | {
|
|
18
|
-
readonly success: false;
|
|
19
|
-
readonly error: "gameNotFound" | "playerNotFound" | "invalidStatus" | "canPlayAtNotReached" | "handFull" | "drawPileEmpty";
|
|
20
|
-
};
|
|
21
|
-
declare function drawCard(gameId: string, playerId: string): DrawCardResult;
|
|
22
|
-
//#endregion
|
|
23
|
-
//#region src/manager/actions/getClientStateAndClearEvents.d.ts
|
|
24
|
-
type GetClientStateAndClearEventsResult = {
|
|
25
|
-
readonly success: true;
|
|
26
|
-
readonly state: ClientState;
|
|
27
|
-
} | {
|
|
28
|
-
readonly success: false;
|
|
29
|
-
readonly error: "gameNotFound" | "playerNotFound";
|
|
30
|
-
};
|
|
31
|
-
declare function getClientStateAndClearEvents(gameId: string, playerId: string): GetClientStateAndClearEventsResult;
|
|
32
|
-
//#endregion
|
|
33
|
-
//#region src/manager/actions/getEventsAndClearAcknowledged.d.ts
|
|
34
|
-
type GetEventsAndClearAcknowledgedResult = {
|
|
35
|
-
readonly success: true;
|
|
36
|
-
readonly events: readonly GameEvent[];
|
|
37
|
-
} | {
|
|
38
|
-
readonly success: false;
|
|
39
|
-
readonly error: "gameNotFound" | "playerNotFound";
|
|
40
|
-
};
|
|
41
|
-
declare function getEventsAndClearAcknowledged(gameId: string, playerId: string, lastReadId: string | null): GetEventsAndClearAcknowledgedResult;
|
|
42
|
-
//#endregion
|
|
43
|
-
//#region src/manager/actions/getJoinableGames.d.ts
|
|
44
|
-
type GetJoinableGamesResult = {
|
|
45
|
-
readonly success: true;
|
|
46
|
-
readonly games: readonly {
|
|
47
|
-
readonly id: string;
|
|
48
|
-
readonly numPlayers: number;
|
|
49
|
-
}[];
|
|
50
|
-
};
|
|
51
|
-
declare function getJoinableGames(): GetJoinableGamesResult;
|
|
52
|
-
//#endregion
|
|
53
|
-
//#region src/manager/actions/joinGame.d.ts
|
|
54
|
-
type JoinGameResult = {
|
|
55
|
-
readonly success: true;
|
|
56
|
-
readonly playerId: string;
|
|
57
|
-
} | {
|
|
58
|
-
readonly success: false;
|
|
59
|
-
readonly error: "gameNotFound" | "invalidStatus" | "maxPlayersReached" | "alreadyInGame";
|
|
60
|
-
};
|
|
61
|
-
declare function joinGame(gameId: string, userId: string, username: string): JoinGameResult;
|
|
62
|
-
//#endregion
|
|
63
|
-
//#region src/manager/actions/leaveGame.d.ts
|
|
64
|
-
type LeaveGameResult = {
|
|
65
|
-
readonly success: true;
|
|
66
|
-
} | {
|
|
67
|
-
readonly success: false;
|
|
68
|
-
readonly error: "gameNotFound" | "playerNotFound";
|
|
69
|
-
};
|
|
70
|
-
declare function leaveGame(gameId: string, playerId: string): LeaveGameResult;
|
|
71
|
-
//#endregion
|
|
72
|
-
//#region src/manager/actions/playCard.d.ts
|
|
73
|
-
type PlayCardResult = {
|
|
74
|
-
readonly success: true;
|
|
75
|
-
} | {
|
|
76
|
-
readonly success: false;
|
|
77
|
-
readonly error: "gameNotFound" | "playerNotFound" | "invalidStatus" | "canPlayAtNotReached" | "cardNotFound" | "cardNotPlayable";
|
|
78
|
-
};
|
|
79
|
-
declare function playCard(gameId: string, playerId: string, cardId: string, isForOtherPlayerPile: boolean): PlayCardResult;
|
|
80
|
-
//#endregion
|
|
81
|
-
//#region src/manager/actions/reportNoPlayableCards.d.ts
|
|
82
|
-
type ReportNoPlayableCardsResult = {
|
|
83
|
-
readonly success: true;
|
|
84
|
-
} | {
|
|
85
|
-
readonly success: false;
|
|
86
|
-
readonly error: "gameNotFound" | "playerNotFound" | "invalidStatus" | "canPlayAtNotReached" | "alreadyReported" | "hasPlayableCard" | "canDraw";
|
|
87
|
-
};
|
|
88
|
-
declare function reportNoPlayableCards(gameId: string, playerId: string): ReportNoPlayableCardsResult;
|
|
89
|
-
//#endregion
|
|
90
|
-
//#region src/manager/actions/sendChat.d.ts
|
|
91
|
-
type SendChatResult = {
|
|
92
|
-
readonly success: true;
|
|
93
|
-
} | {
|
|
94
|
-
readonly success: false;
|
|
95
|
-
readonly error: "gameNotFound" | "playerNotFound";
|
|
96
|
-
};
|
|
97
|
-
declare function sendChat(gameId: string, playerId: string, text: string): SendChatResult;
|
|
98
|
-
//#endregion
|
|
99
|
-
//#region src/manager/actions/startGame.d.ts
|
|
100
|
-
type StartGameResult = {
|
|
101
|
-
readonly success: true;
|
|
102
|
-
} | {
|
|
103
|
-
readonly success: false;
|
|
104
|
-
readonly error: "gameNotFound" | "playerNotFound" | "invalidStatus" | "playerNotAdmin" | "minPlayersNotReached";
|
|
105
|
-
};
|
|
106
|
-
declare function startGame(gameId: string, playerId: string): StartGameResult;
|
|
107
|
-
//#endregion
|
|
108
|
-
export { createGame, drawCard, getClientStateAndClearEvents, getEventsAndClearAcknowledged, getJoinableGames, joinGame, leaveGame, playCard, reportNoPlayableCards, sendChat, startGame };
|
|
109
|
-
//# sourceMappingURL=index.d.mts.map
|
|
1
|
+
import { a as leaveGame, c as getEventsAndClearAcknowledged, d as ClientState, f as ChatMessage, h as createGame, i as playCard, l as GameEvent, m as drawCard, n as sendChat, o as joinGame, p as Card, r as reportNoPlayableCards, s as getJoinableGames, t as startGame, u as getClientStateAndClearEvents } from "../index-BilCO_4a.mjs";
|
|
2
|
+
export { type Card, type ChatMessage, type ClientState, type GameEvent, createGame, drawCard, getClientStateAndClearEvents, getEventsAndClearAcknowledged, getJoinableGames, joinGame, leaveGame, playCard, reportNoPlayableCards, sendChat, startGame };
|
package/dist/manager/index.mjs
CHANGED
|
@@ -1,22 +1,2 @@
|
|
|
1
|
-
import { a as leaveGame, c as getEventsAndClearAcknowledged, d as createGame,
|
|
2
|
-
//#region src/manager/watchdog.ts
|
|
3
|
-
var Watchdog = class {
|
|
4
|
-
start() {
|
|
5
|
-
console.log(`watchdog start at ${Date.now()} (${GAME_KEY})`);
|
|
6
|
-
setInterval(() => this.wakeUp(), WATCHDOG_INTERVAL_MS);
|
|
7
|
-
}
|
|
8
|
-
wakeUp() {
|
|
9
|
-
const now = Date.now();
|
|
10
|
-
for (const game of games.values()) if (game.expiresAt <= now) {
|
|
11
|
-
games.delete(game.id);
|
|
12
|
-
console.log(`watchdog purged ${game.id} (${GAME_KEY})`);
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
};
|
|
16
|
-
//#endregion
|
|
17
|
-
//#region src/manager/index.ts
|
|
18
|
-
new Watchdog().start();
|
|
19
|
-
//#endregion
|
|
1
|
+
import { a as leaveGame, c as getEventsAndClearAcknowledged, d as createGame, i as playCard, l as getClientStateAndClearEvents, n as sendChat, o as joinGame, r as reportNoPlayableCards, s as getJoinableGames, t as startGame, u as drawCard } from "../manager-CPmezdJa.mjs";
|
|
20
2
|
export { createGame, drawCard, getClientStateAndClearEvents, getEventsAndClearAcknowledged, getJoinableGames, joinGame, leaveGame, playCard, reportNoPlayableCards, sendChat, startGame };
|
|
21
|
-
|
|
22
|
-
//# sourceMappingURL=index.mjs.map
|
|
@@ -269,6 +269,22 @@ const CARDS = [
|
|
|
269
269
|
//#region src/manager/games.ts
|
|
270
270
|
const games = /* @__PURE__ */ new Map();
|
|
271
271
|
//#endregion
|
|
272
|
+
//#region src/manager/watchdog.ts
|
|
273
|
+
var Watchdog = class {
|
|
274
|
+
start() {
|
|
275
|
+
console.log(`watchdog start at ${Date.now()} (${GAME_KEY})`);
|
|
276
|
+
setInterval(() => this.wakeUp(), WATCHDOG_INTERVAL_MS);
|
|
277
|
+
}
|
|
278
|
+
wakeUp() {
|
|
279
|
+
const now = Date.now();
|
|
280
|
+
for (const game of games.values()) if (game.expiresAt <= now) {
|
|
281
|
+
games.delete(game.id);
|
|
282
|
+
console.log(`watchdog purged ${game.id} (${GAME_KEY})`);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
const watchdog = new Watchdog();
|
|
287
|
+
//#endregion
|
|
272
288
|
//#region src/manager/actions/createGame.ts
|
|
273
289
|
function createGame(userId, username) {
|
|
274
290
|
if (games.size === 50) return {
|
|
@@ -810,6 +826,9 @@ function startGame(gameId, playerId) {
|
|
|
810
826
|
return { success: true };
|
|
811
827
|
}
|
|
812
828
|
//#endregion
|
|
813
|
-
|
|
829
|
+
//#region src/manager/index.ts
|
|
830
|
+
watchdog.start();
|
|
831
|
+
//#endregion
|
|
832
|
+
export { leaveGame as a, getEventsAndClearAcknowledged as c, createGame as d, playCard as i, getClientStateAndClearEvents as l, sendChat as n, joinGame as o, reportNoPlayableCards as r, getJoinableGames as s, startGame as t, drawCard as u };
|
|
814
833
|
|
|
815
|
-
//# sourceMappingURL=
|
|
834
|
+
//# sourceMappingURL=manager-CPmezdJa.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager-CPmezdJa.mjs","names":[],"sources":["../src/manager/constants.ts","../src/manager/games.ts","../src/manager/watchdog.ts","../src/manager/actions/createGame.ts","../src/lib/emitEvent.ts","../src/lib/emitEventToPlayer.ts","../src/manager/actions/drawCard.ts","../src/manager/actions/getClientStateAndClearEvents.ts","../src/manager/actions/getEventsAndClearAcknowledged.ts","../src/manager/actions/getJoinableGames.ts","../src/manager/actions/joinGame.ts","../src/manager/actions/leaveGame.ts","../src/manager/lib/isCardPlayable.ts","../src/manager/lib/hasPlayableCard.ts","../src/manager/actions/playCard.ts","../src/lib/shuffleCards.ts","../src/manager/actions/reportNoPlayableCards.ts","../src/manager/actions/sendChat.ts","../src/manager/actions/startGame.ts","../src/manager/index.ts"],"sourcesContent":["import type { Card } from \"./types/Card.js\";\n\nexport const GAME_KEY = \"speed\";\nexport const MAX_GAMES = 50;\nexport const WATCHDOG_INTERVAL_MS = 10000;\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 type { Game } from \"./types/Game.js\";\n\nexport const games = new Map<string, Game>();\n","import { GAME_KEY, WATCHDOG_INTERVAL_MS } from \"./constants.js\";\nimport { games } from \"./games.js\";\n\nclass Watchdog {\n start() {\n console.log(`watchdog start at ${Date.now()} (${GAME_KEY})`);\n setInterval(() => this.wakeUp(), WATCHDOG_INTERVAL_MS);\n }\n\n wakeUp() {\n const now = Date.now();\n // console.log(`watchdog wakeUp at ${now} (${GAME_KEY})`);\n for (const game of games.values()) {\n if (game.expiresAt <= now) {\n games.delete(game.id);\n console.log(`watchdog purged ${game.id} (${GAME_KEY})`);\n }\n }\n }\n}\n\nexport const watchdog = new Watchdog();\n","import { EXPIRY_EXTENSION_MS, MAX_GAMES } from \"../constants.js\";\nimport { games } from \"../games.js\";\nimport type { Player } from \"../types/Player.js\";\nimport type { Game } from \"../types/Game.js\";\n\ntype 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 function createGame(userId: string, username: string): CreateGameResult {\n if (games.size === MAX_GAMES) {\n return { success: false, error: \"maxGamesReached\" };\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 const createdAt = Date.now();\n const game: Game = {\n status: \"open\",\n id: crypto.randomUUID(),\n createdAt,\n expiresAt: createdAt + EXPIRY_EXTENSION_MS,\n chatMessages: [],\n players: [player],\n };\n games.set(game.id, game);\n return { success: true, gameId: game.id, 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 { games } from \"../games.js\";\n\ntype 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 function drawCard(gameId: string, playerId: string): DrawCardResult {\n const game = games.get(gameId);\n if (!game) {\n return { success: false, error: \"gameNotFound\" };\n }\n const player = game.players.find((p) => p.id === playerId);\n if (!player) {\n return { success: false, error: \"playerNotFound\" };\n }\n if (game.status !== \"started\") {\n return { success: false, error: \"invalidStatus\" };\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 };\n}\n","import { games } from \"../games.js\";\nimport type { ClientState } from \"../types/ClientState.js\";\n\ntype GetClientStateAndClearEventsResult =\n | {\n readonly success: true;\n readonly state: ClientState;\n }\n | {\n readonly success: false;\n readonly error: \"gameNotFound\" | \"playerNotFound\";\n };\n\nexport function getClientStateAndClearEvents(\n gameId: string,\n playerId: string,\n): GetClientStateAndClearEventsResult {\n const game = games.get(gameId);\n if (!game) {\n return { success: false, error: \"gameNotFound\" };\n }\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,\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 };\n}\n","import { games } from \"../games.js\";\nimport type { GameEvent } from \"../types/GameEvent.js\";\n\ntype 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 function getEventsAndClearAcknowledged(\n gameId: string,\n playerId: string,\n lastReadId: string | null,\n): GetEventsAndClearAcknowledgedResult {\n const game = games.get(gameId);\n if (!game) {\n return { success: false, error: \"gameNotFound\" };\n }\n const player = game.players.find((p) => p.id === playerId);\n if (!player) {\n return { success: false, error: \"playerNotFound\" };\n }\n const lastReadEventIndex = player.events.findIndex(\n (e) => e.id === lastReadId,\n );\n player.events.splice(0, lastReadEventIndex + 1);\n return { success: true, events: player.events };\n}\n","import { MAX_PLAYERS } from \"../constants.js\";\nimport { games } from \"../games.js\";\n\ntype GetJoinableGamesResult = {\n readonly success: true;\n readonly games: readonly {\n readonly id: string;\n readonly numPlayers: number;\n }[];\n};\n\nexport function getJoinableGames(): GetJoinableGamesResult {\n return {\n success: true,\n games: Array.from(games.values())\n .filter((g) => g.status === \"open\" && g.players.length < MAX_PLAYERS)\n .map((g) => ({\n id: g.id,\n numPlayers: g.players.length,\n })),\n };\n}\n","import { emitEvent } from \"../../lib/emitEvent.js\";\nimport { MAX_PLAYERS } from \"../constants.js\";\nimport { games } from \"../games.js\";\nimport type { Player } from \"../types/Player.js\";\n\ntype 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 function joinGame(\n gameId: string,\n userId: string,\n username: string,\n): JoinGameResult {\n const game = games.get(gameId);\n if (!game) {\n return { success: false, error: \"gameNotFound\" };\n }\n if (game.status !== \"open\") {\n return { success: false, error: \"invalidStatus\" };\n }\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, playerId: player.id };\n}\n","import { emitEvent } from \"../../lib/emitEvent.js\";\nimport { EXPIRY_EXTENSION_MS, MIN_PLAYERS } from \"../constants.js\";\nimport { games } from \"../games.js\";\nimport type { Game } from \"../types/Game.js\";\n\ntype LeaveGameResult =\n | {\n readonly success: true;\n }\n | {\n readonly success: false;\n readonly error: \"gameNotFound\" | \"playerNotFound\";\n };\n\nexport function leaveGame(gameId: string, playerId: string): LeaveGameResult {\n const game = games.get(gameId);\n if (!game) {\n return { success: false, error: \"gameNotFound\" };\n }\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 games.set(game.id, forfeitedGame);\n emitEvent(forfeitedGame, { type: \"gameForfeited\" });\n emitEvent(forfeitedGame, {\n type: \"expirationUpdated\",\n expiresAt: forfeitedGame.expiresAt,\n });\n }\n if (game.players.length === 0) {\n games.delete(game.id);\n }\n return { success: true };\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 { games } from \"../games.js\";\nimport { hasPlayableCard } from \"../lib/hasPlayableCard.js\";\nimport { isCardPlayable } from \"../lib/isCardPlayable.js\";\nimport type { Game } from \"../types/Game.js\";\n\ntype 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 function playCard(\n gameId: string,\n playerId: string,\n cardId: string,\n isForOtherPlayerPile: boolean,\n): PlayCardResult {\n const game = games.get(gameId);\n if (!game) {\n return { success: false, error: \"gameNotFound\" };\n }\n const player = game.players.find((p) => p.id === playerId);\n if (!player) {\n return { success: false, error: \"playerNotFound\" };\n }\n if (game.status !== \"started\") {\n return { success: false, error: \"invalidStatus\" };\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: Game = {\n ...game,\n status: \"completed\",\n };\n games.set(game.id, completedGame);\n }\n\n return { success: true };\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 { games } from \"../games.js\";\nimport { hasPlayableCard } from \"../lib/hasPlayableCard.js\";\n\ntype 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 function reportNoPlayableCards(\n gameId: string,\n playerId: string,\n): ReportNoPlayableCardsResult {\n const game = games.get(gameId);\n if (!game) {\n return { success: false, error: \"gameNotFound\" };\n }\n const player = game.players.find((p) => p.id === playerId);\n if (!player) {\n return { success: false, error: \"playerNotFound\" };\n }\n if (game.status !== \"started\") {\n return { success: false, error: \"invalidStatus\" };\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 };\n}\n","import { emitEvent } from \"../../lib/emitEvent.js\";\nimport { games } from \"../games.js\";\nimport type { ChatMessage } from \"../types/ChatMessage.js\";\n\ntype SendChatResult =\n | {\n readonly success: true;\n }\n | {\n readonly success: false;\n readonly error: \"gameNotFound\" | \"playerNotFound\";\n };\n\nexport function sendChat(\n gameId: string,\n playerId: string,\n text: string,\n): SendChatResult {\n const game = games.get(gameId);\n if (!game) {\n return { success: false, error: \"gameNotFound\" };\n }\n const player = game.players.find((p) => p.id === playerId);\n if (!player) {\n return { success: false, error: \"playerNotFound\" };\n }\n const message: ChatMessage = {\n id: crypto.randomUUID(),\n username: player.username,\n text,\n };\n game.chatMessages.push(message);\n emitEvent(game, { type: \"chat\", message });\n return { success: true };\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 { games } from \"../games.js\";\nimport type { Game } from \"../types/Game.js\";\n\ntype StartGameResult =\n | {\n readonly success: true;\n }\n | {\n readonly success: false;\n readonly error:\n | \"gameNotFound\"\n | \"playerNotFound\"\n | \"invalidStatus\"\n | \"playerNotAdmin\"\n | \"minPlayersNotReached\";\n };\n\nexport function startGame(gameId: string, playerId: string): StartGameResult {\n const game = games.get(gameId);\n if (!game) {\n return { success: false, error: \"gameNotFound\" };\n }\n const player = game.players.find((p) => p.id === playerId);\n if (!player) {\n return { success: false, error: \"playerNotFound\" };\n }\n if (game.status !== \"open\") {\n return { success: false, error: \"invalidStatus\" };\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: Game = {\n ...game,\n status: \"started\",\n expiresAt: Date.now() + EXPIRY_EXTENSION_MS,\n canPlayAt: Date.now() + CAN_PLAY_AT_DELAY_MS,\n };\n 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 };\n}\n","import { watchdog } from \"./watchdog.js\";\n\nexport { createGame } from \"./actions/createGame.js\";\nexport { drawCard } from \"./actions/drawCard.js\";\nexport { getClientStateAndClearEvents } from \"./actions/getClientStateAndClearEvents.js\";\nexport { getEventsAndClearAcknowledged } from \"./actions/getEventsAndClearAcknowledged.js\";\nexport { getJoinableGames } from \"./actions/getJoinableGames.js\";\nexport { joinGame } from \"./actions/joinGame.js\";\nexport { leaveGame } from \"./actions/leaveGame.js\";\nexport { playCard } from \"./actions/playCard.js\";\nexport { reportNoPlayableCards } from \"./actions/reportNoPlayableCards.js\";\nexport { sendChat } from \"./actions/sendChat.js\";\nexport { startGame } from \"./actions/startGame.js\";\n\nexport type { Card } from \"./types/Card.js\";\nexport type { ChatMessage } from \"./types/ChatMessage.js\";\nexport type { ClientState } from \"./types/ClientState.js\";\nexport type { GameEvent } from \"./types/GameEvent.js\";\n\nwatchdog.start();\n"],"mappings":"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"}
|
|
@@ -269,6 +269,22 @@ const CARDS = [
|
|
|
269
269
|
//#region src/manager/games.ts
|
|
270
270
|
const games = /* @__PURE__ */ new Map();
|
|
271
271
|
//#endregion
|
|
272
|
+
//#region src/manager/watchdog.ts
|
|
273
|
+
var Watchdog = class {
|
|
274
|
+
start() {
|
|
275
|
+
console.log(`watchdog start at ${Date.now()} (${GAME_KEY})`);
|
|
276
|
+
setInterval(() => this.wakeUp(), WATCHDOG_INTERVAL_MS);
|
|
277
|
+
}
|
|
278
|
+
wakeUp() {
|
|
279
|
+
const now = Date.now();
|
|
280
|
+
for (const game of games.values()) if (game.expiresAt <= now) {
|
|
281
|
+
games.delete(game.id);
|
|
282
|
+
console.log(`watchdog purged ${game.id} (${GAME_KEY})`);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
const watchdog = new Watchdog();
|
|
287
|
+
//#endregion
|
|
272
288
|
//#region src/manager/actions/createGame.ts
|
|
273
289
|
function createGame(userId, username) {
|
|
274
290
|
if (games.size === 50) return {
|
|
@@ -810,18 +826,9 @@ function startGame(gameId, playerId) {
|
|
|
810
826
|
return { success: true };
|
|
811
827
|
}
|
|
812
828
|
//#endregion
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
return GAME_KEY;
|
|
817
|
-
}
|
|
818
|
-
});
|
|
819
|
-
Object.defineProperty(exports, "WATCHDOG_INTERVAL_MS", {
|
|
820
|
-
enumerable: true,
|
|
821
|
-
get: function() {
|
|
822
|
-
return WATCHDOG_INTERVAL_MS;
|
|
823
|
-
}
|
|
824
|
-
});
|
|
829
|
+
//#region src/manager/index.ts
|
|
830
|
+
watchdog.start();
|
|
831
|
+
//#endregion
|
|
825
832
|
Object.defineProperty(exports, "createGame", {
|
|
826
833
|
enumerable: true,
|
|
827
834
|
get: function() {
|
|
@@ -834,12 +841,6 @@ Object.defineProperty(exports, "drawCard", {
|
|
|
834
841
|
return drawCard;
|
|
835
842
|
}
|
|
836
843
|
});
|
|
837
|
-
Object.defineProperty(exports, "games", {
|
|
838
|
-
enumerable: true,
|
|
839
|
-
get: function() {
|
|
840
|
-
return games;
|
|
841
|
-
}
|
|
842
|
-
});
|
|
843
844
|
Object.defineProperty(exports, "getClientStateAndClearEvents", {
|
|
844
845
|
enumerable: true,
|
|
845
846
|
get: function() {
|
|
@@ -895,4 +896,4 @@ Object.defineProperty(exports, "startGame", {
|
|
|
895
896
|
}
|
|
896
897
|
});
|
|
897
898
|
|
|
898
|
-
//# sourceMappingURL=
|
|
899
|
+
//# sourceMappingURL=manager-DErQ_XUq.cjs.map
|