@thegeem/protocol 0.1.9 → 0.1.10
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/index.cjs +20 -2
- package/dist/index.d.cts +26 -3
- package/dist/index.d.ts +26 -3
- package/dist/index.js +16 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -23,8 +23,11 @@ __export(index_exports, {
|
|
|
23
23
|
ClientMsg: () => ClientMsg,
|
|
24
24
|
GAME_IDS: () => GAME_IDS,
|
|
25
25
|
LIMITS: () => LIMITS,
|
|
26
|
+
MODES: () => MODES,
|
|
27
|
+
MODE_IDS: () => MODE_IDS,
|
|
26
28
|
PROTOCOL_VERSION: () => PROTOCOL_VERSION,
|
|
27
|
-
ROOM_ALPHABET: () => ROOM_ALPHABET
|
|
29
|
+
ROOM_ALPHABET: () => ROOM_ALPHABET,
|
|
30
|
+
modesForGame: () => modesForGame
|
|
28
31
|
});
|
|
29
32
|
module.exports = __toCommonJS(index_exports);
|
|
30
33
|
var import_zod = require("zod");
|
|
@@ -36,6 +39,14 @@ var LIMITS = {
|
|
|
36
39
|
};
|
|
37
40
|
var PROTOCOL_VERSION = 1;
|
|
38
41
|
var GAME_IDS = ["trivia"];
|
|
42
|
+
var MODE_IDS = ["solo", "oneDevice", "snag", "multiplayer"];
|
|
43
|
+
var MODES = [
|
|
44
|
+
{ id: "solo", gameId: "trivia", label: "Solo", onlineEligible: false },
|
|
45
|
+
{ id: "oneDevice", gameId: "trivia", label: "One Device", onlineEligible: false },
|
|
46
|
+
{ id: "snag", gameId: "trivia", label: "Snag", onlineEligible: true },
|
|
47
|
+
{ id: "multiplayer", gameId: "trivia", label: "Multiplayer", onlineEligible: true }
|
|
48
|
+
];
|
|
49
|
+
var modesForGame = (gameId) => MODES.filter((m) => m.gameId === gameId);
|
|
39
50
|
var ROOM_ALPHABET = "ACDEFGHJKMNPQRTUVWXY2346789";
|
|
40
51
|
var UNSAFE_CHARS = /[\p{Cc}<>]/gu;
|
|
41
52
|
var DisplayName = import_zod.z.string().trim().min(1).max(LIMITS.MAX_NAME_LEN).transform((s) => s.replace(UNSAFE_CHARS, "").trim()).refine((s) => s.length >= 1, "name is empty after sanitizing");
|
|
@@ -85,6 +96,10 @@ var ClientMsg = import_zod.z.discriminatedUnion("t", [
|
|
|
85
96
|
// which game to play; defaults to 'trivia'
|
|
86
97
|
totalRounds: import_zod.z.number().int().min(1).max(50),
|
|
87
98
|
categoryIds: import_zod.z.array(import_zod.z.string().max(60)).min(1).max(12),
|
|
99
|
+
// PREFERRED: pick a mode from the registry (see MODES). The server maps it to the engine
|
|
100
|
+
// rules. Send this and omit buzzerMode/noHost. Falls back to the legacy flags below if omitted.
|
|
101
|
+
modeId: import_zod.z.enum(MODE_IDS).optional(),
|
|
102
|
+
// LEGACY (pre-modeId clients) — the raw engine flags. Ignored when modeId is present.
|
|
88
103
|
// How to play (maps to the engine). Omit → controller (each player answers from
|
|
89
104
|
// their own device). 'off' = one device drives (Me-Controller); pair with noHost.
|
|
90
105
|
// solo=Solo · race=Snag/buzz · controller=each-player-from-device · off=Me-Controller
|
|
@@ -120,6 +135,9 @@ var ClientMsg = import_zod.z.discriminatedUnion("t", [
|
|
|
120
135
|
ClientMsg,
|
|
121
136
|
GAME_IDS,
|
|
122
137
|
LIMITS,
|
|
138
|
+
MODES,
|
|
139
|
+
MODE_IDS,
|
|
123
140
|
PROTOCOL_VERSION,
|
|
124
|
-
ROOM_ALPHABET
|
|
141
|
+
ROOM_ALPHABET,
|
|
142
|
+
modesForGame
|
|
125
143
|
});
|
package/dist/index.d.cts
CHANGED
|
@@ -37,6 +37,26 @@ declare const PROTOCOL_VERSION = 1;
|
|
|
37
37
|
*/
|
|
38
38
|
declare const GAME_IDS: readonly ["trivia"];
|
|
39
39
|
type GameId = (typeof GAME_IDS)[number];
|
|
40
|
+
/**
|
|
41
|
+
* The MODE REGISTRY — the list of ways to play each game. A client renders its mode picker from this
|
|
42
|
+
* and sends the chosen `modeId` on `startGame`; the SERVER owns the modeId → engine-rules mapping (the
|
|
43
|
+
* flags are an internal relay detail, not the client's job). Adding a mode = one entry here. Game #2
|
|
44
|
+
* gets its own `gameId` rows. `label` is a short English label — clients may localize by `id` (Arabic
|
|
45
|
+
* UI is Kuwaiti). `onlineEligible` = a finished game in this mode counts toward the global leaderboard
|
|
46
|
+
* (only server-arbitrated, multi-device modes; single-device/solo are local-only — the host controls
|
|
47
|
+
* input, so the server can't trust the score).
|
|
48
|
+
*/
|
|
49
|
+
declare const MODE_IDS: readonly ["solo", "oneDevice", "snag", "multiplayer"];
|
|
50
|
+
type ModeId = (typeof MODE_IDS)[number];
|
|
51
|
+
interface ModeInfo {
|
|
52
|
+
id: ModeId;
|
|
53
|
+
gameId: GameId;
|
|
54
|
+
label: string;
|
|
55
|
+
onlineEligible: boolean;
|
|
56
|
+
}
|
|
57
|
+
declare const MODES: readonly ModeInfo[];
|
|
58
|
+
/** The modes available for a given game (for a client's mode picker). */
|
|
59
|
+
declare const modesForGame: (gameId: GameId) => ModeInfo[];
|
|
40
60
|
/** Unambiguous room-code alphabet — no 0/O, 1/I/L. */
|
|
41
61
|
declare const ROOM_ALPHABET = "ACDEFGHJKMNPQRTUVWXY2346789";
|
|
42
62
|
declare const HelpType: z.ZodEnum<["removeTwoAnswers", "changeQuestion", "extraTime", "doublePoints", "stealPoints", "restPlayer", "tripLevel"]>;
|
|
@@ -228,6 +248,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
|
|
|
228
248
|
game: z.ZodOptional<z.ZodEnum<["trivia"]>>;
|
|
229
249
|
totalRounds: z.ZodNumber;
|
|
230
250
|
categoryIds: z.ZodArray<z.ZodString, "many">;
|
|
251
|
+
modeId: z.ZodOptional<z.ZodEnum<["solo", "oneDevice", "snag", "multiplayer"]>>;
|
|
231
252
|
buzzerMode: z.ZodOptional<z.ZodEnum<["off", "solo", "race", "controller"]>>;
|
|
232
253
|
noHost: z.ZodOptional<z.ZodBoolean>;
|
|
233
254
|
}, "strip", z.ZodTypeAny, {
|
|
@@ -235,14 +256,16 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
|
|
|
235
256
|
categoryIds: string[];
|
|
236
257
|
totalRounds: number;
|
|
237
258
|
game?: "trivia" | undefined;
|
|
238
|
-
|
|
259
|
+
modeId?: "solo" | "oneDevice" | "snag" | "multiplayer" | undefined;
|
|
260
|
+
buzzerMode?: "solo" | "off" | "race" | "controller" | undefined;
|
|
239
261
|
noHost?: boolean | undefined;
|
|
240
262
|
}, {
|
|
241
263
|
t: "startGame";
|
|
242
264
|
categoryIds: string[];
|
|
243
265
|
totalRounds: number;
|
|
244
266
|
game?: "trivia" | undefined;
|
|
245
|
-
|
|
267
|
+
modeId?: "solo" | "oneDevice" | "snag" | "multiplayer" | undefined;
|
|
268
|
+
buzzerMode?: "solo" | "off" | "race" | "controller" | undefined;
|
|
246
269
|
noHost?: boolean | undefined;
|
|
247
270
|
}>, z.ZodObject<{
|
|
248
271
|
t: z.ZodLiteral<"pickLevel">;
|
|
@@ -549,4 +572,4 @@ type ServerMsg = {
|
|
|
549
572
|
message: string;
|
|
550
573
|
};
|
|
551
574
|
|
|
552
|
-
export { type AvatarView, type BuzzerGameMode, type CategoryView, ClientMsg, type Effect, GAME_IDS, type GameId, type GameStateView, type GameStatus, type GameplayFlow, type HelpName, LIMITS, type LobbyPlayer, PROTOCOL_VERSION, type QuestionView, ROOM_ALPHABET, type ServerMsg, type SoundName, type TeamSlotView, type TeamView, type YouContext };
|
|
575
|
+
export { type AvatarView, type BuzzerGameMode, type CategoryView, ClientMsg, type Effect, GAME_IDS, type GameId, type GameStateView, type GameStatus, type GameplayFlow, type HelpName, LIMITS, type LobbyPlayer, MODES, MODE_IDS, type ModeId, type ModeInfo, PROTOCOL_VERSION, type QuestionView, ROOM_ALPHABET, type ServerMsg, type SoundName, type TeamSlotView, type TeamView, type YouContext, modesForGame };
|
package/dist/index.d.ts
CHANGED
|
@@ -37,6 +37,26 @@ declare const PROTOCOL_VERSION = 1;
|
|
|
37
37
|
*/
|
|
38
38
|
declare const GAME_IDS: readonly ["trivia"];
|
|
39
39
|
type GameId = (typeof GAME_IDS)[number];
|
|
40
|
+
/**
|
|
41
|
+
* The MODE REGISTRY — the list of ways to play each game. A client renders its mode picker from this
|
|
42
|
+
* and sends the chosen `modeId` on `startGame`; the SERVER owns the modeId → engine-rules mapping (the
|
|
43
|
+
* flags are an internal relay detail, not the client's job). Adding a mode = one entry here. Game #2
|
|
44
|
+
* gets its own `gameId` rows. `label` is a short English label — clients may localize by `id` (Arabic
|
|
45
|
+
* UI is Kuwaiti). `onlineEligible` = a finished game in this mode counts toward the global leaderboard
|
|
46
|
+
* (only server-arbitrated, multi-device modes; single-device/solo are local-only — the host controls
|
|
47
|
+
* input, so the server can't trust the score).
|
|
48
|
+
*/
|
|
49
|
+
declare const MODE_IDS: readonly ["solo", "oneDevice", "snag", "multiplayer"];
|
|
50
|
+
type ModeId = (typeof MODE_IDS)[number];
|
|
51
|
+
interface ModeInfo {
|
|
52
|
+
id: ModeId;
|
|
53
|
+
gameId: GameId;
|
|
54
|
+
label: string;
|
|
55
|
+
onlineEligible: boolean;
|
|
56
|
+
}
|
|
57
|
+
declare const MODES: readonly ModeInfo[];
|
|
58
|
+
/** The modes available for a given game (for a client's mode picker). */
|
|
59
|
+
declare const modesForGame: (gameId: GameId) => ModeInfo[];
|
|
40
60
|
/** Unambiguous room-code alphabet — no 0/O, 1/I/L. */
|
|
41
61
|
declare const ROOM_ALPHABET = "ACDEFGHJKMNPQRTUVWXY2346789";
|
|
42
62
|
declare const HelpType: z.ZodEnum<["removeTwoAnswers", "changeQuestion", "extraTime", "doublePoints", "stealPoints", "restPlayer", "tripLevel"]>;
|
|
@@ -228,6 +248,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
|
|
|
228
248
|
game: z.ZodOptional<z.ZodEnum<["trivia"]>>;
|
|
229
249
|
totalRounds: z.ZodNumber;
|
|
230
250
|
categoryIds: z.ZodArray<z.ZodString, "many">;
|
|
251
|
+
modeId: z.ZodOptional<z.ZodEnum<["solo", "oneDevice", "snag", "multiplayer"]>>;
|
|
231
252
|
buzzerMode: z.ZodOptional<z.ZodEnum<["off", "solo", "race", "controller"]>>;
|
|
232
253
|
noHost: z.ZodOptional<z.ZodBoolean>;
|
|
233
254
|
}, "strip", z.ZodTypeAny, {
|
|
@@ -235,14 +256,16 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
|
|
|
235
256
|
categoryIds: string[];
|
|
236
257
|
totalRounds: number;
|
|
237
258
|
game?: "trivia" | undefined;
|
|
238
|
-
|
|
259
|
+
modeId?: "solo" | "oneDevice" | "snag" | "multiplayer" | undefined;
|
|
260
|
+
buzzerMode?: "solo" | "off" | "race" | "controller" | undefined;
|
|
239
261
|
noHost?: boolean | undefined;
|
|
240
262
|
}, {
|
|
241
263
|
t: "startGame";
|
|
242
264
|
categoryIds: string[];
|
|
243
265
|
totalRounds: number;
|
|
244
266
|
game?: "trivia" | undefined;
|
|
245
|
-
|
|
267
|
+
modeId?: "solo" | "oneDevice" | "snag" | "multiplayer" | undefined;
|
|
268
|
+
buzzerMode?: "solo" | "off" | "race" | "controller" | undefined;
|
|
246
269
|
noHost?: boolean | undefined;
|
|
247
270
|
}>, z.ZodObject<{
|
|
248
271
|
t: z.ZodLiteral<"pickLevel">;
|
|
@@ -549,4 +572,4 @@ type ServerMsg = {
|
|
|
549
572
|
message: string;
|
|
550
573
|
};
|
|
551
574
|
|
|
552
|
-
export { type AvatarView, type BuzzerGameMode, type CategoryView, ClientMsg, type Effect, GAME_IDS, type GameId, type GameStateView, type GameStatus, type GameplayFlow, type HelpName, LIMITS, type LobbyPlayer, PROTOCOL_VERSION, type QuestionView, ROOM_ALPHABET, type ServerMsg, type SoundName, type TeamSlotView, type TeamView, type YouContext };
|
|
575
|
+
export { type AvatarView, type BuzzerGameMode, type CategoryView, ClientMsg, type Effect, GAME_IDS, type GameId, type GameStateView, type GameStatus, type GameplayFlow, type HelpName, LIMITS, type LobbyPlayer, MODES, MODE_IDS, type ModeId, type ModeInfo, PROTOCOL_VERSION, type QuestionView, ROOM_ALPHABET, type ServerMsg, type SoundName, type TeamSlotView, type TeamView, type YouContext, modesForGame };
|
package/dist/index.js
CHANGED
|
@@ -8,6 +8,14 @@ var LIMITS = {
|
|
|
8
8
|
};
|
|
9
9
|
var PROTOCOL_VERSION = 1;
|
|
10
10
|
var GAME_IDS = ["trivia"];
|
|
11
|
+
var MODE_IDS = ["solo", "oneDevice", "snag", "multiplayer"];
|
|
12
|
+
var MODES = [
|
|
13
|
+
{ id: "solo", gameId: "trivia", label: "Solo", onlineEligible: false },
|
|
14
|
+
{ id: "oneDevice", gameId: "trivia", label: "One Device", onlineEligible: false },
|
|
15
|
+
{ id: "snag", gameId: "trivia", label: "Snag", onlineEligible: true },
|
|
16
|
+
{ id: "multiplayer", gameId: "trivia", label: "Multiplayer", onlineEligible: true }
|
|
17
|
+
];
|
|
18
|
+
var modesForGame = (gameId) => MODES.filter((m) => m.gameId === gameId);
|
|
11
19
|
var ROOM_ALPHABET = "ACDEFGHJKMNPQRTUVWXY2346789";
|
|
12
20
|
var UNSAFE_CHARS = /[\p{Cc}<>]/gu;
|
|
13
21
|
var DisplayName = z.string().trim().min(1).max(LIMITS.MAX_NAME_LEN).transform((s) => s.replace(UNSAFE_CHARS, "").trim()).refine((s) => s.length >= 1, "name is empty after sanitizing");
|
|
@@ -57,6 +65,10 @@ var ClientMsg = z.discriminatedUnion("t", [
|
|
|
57
65
|
// which game to play; defaults to 'trivia'
|
|
58
66
|
totalRounds: z.number().int().min(1).max(50),
|
|
59
67
|
categoryIds: z.array(z.string().max(60)).min(1).max(12),
|
|
68
|
+
// PREFERRED: pick a mode from the registry (see MODES). The server maps it to the engine
|
|
69
|
+
// rules. Send this and omit buzzerMode/noHost. Falls back to the legacy flags below if omitted.
|
|
70
|
+
modeId: z.enum(MODE_IDS).optional(),
|
|
71
|
+
// LEGACY (pre-modeId clients) — the raw engine flags. Ignored when modeId is present.
|
|
60
72
|
// How to play (maps to the engine). Omit → controller (each player answers from
|
|
61
73
|
// their own device). 'off' = one device drives (Me-Controller); pair with noHost.
|
|
62
74
|
// solo=Solo · race=Snag/buzz · controller=each-player-from-device · off=Me-Controller
|
|
@@ -91,6 +103,9 @@ export {
|
|
|
91
103
|
ClientMsg,
|
|
92
104
|
GAME_IDS,
|
|
93
105
|
LIMITS,
|
|
106
|
+
MODES,
|
|
107
|
+
MODE_IDS,
|
|
94
108
|
PROTOCOL_VERSION,
|
|
95
|
-
ROOM_ALPHABET
|
|
109
|
+
ROOM_ALPHABET,
|
|
110
|
+
modesForGame
|
|
96
111
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thegeem/protocol",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.10",
|
|
4
4
|
"description": "Geem's wire protocol — shared zod schemas + TypeScript types for talking to the Geem game server over Socket.IO. The source of truth all clients implement against.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"homepage": "https://geem.tv",
|