@thegeem/protocol 0.1.10 → 0.1.12

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 CHANGED
@@ -63,18 +63,19 @@ var HelpType = import_zod.z.enum([
63
63
  ]);
64
64
  var Pv = import_zod.z.number().int().min(1).max(1e6).optional();
65
65
  var IdToken = import_zod.z.string().max(4096).optional();
66
+ var Platform = import_zod.z.enum(["web", "ios", "android"]).optional();
66
67
  var Avatar = import_zod.z.object({
67
68
  emoji: import_zod.z.string().min(1).max(16).transform((s) => s.replace(UNSAFE_CHARS, "")).refine((s) => s.length >= 1, "empty emoji"),
68
69
  color: import_zod.z.string().regex(/^#[0-9a-fA-F]{6}$/, "color must be #rrggbb")
69
70
  });
70
71
  var ClientMsg = import_zod.z.discriminatedUnion("t", [
71
72
  // room / lobby
72
- import_zod.z.object({ t: import_zod.z.literal("createRoom"), name: DisplayName.optional(), avatar: Avatar.optional(), pv: Pv, idToken: IdToken }),
73
+ import_zod.z.object({ t: import_zod.z.literal("createRoom"), name: DisplayName.optional(), avatar: Avatar.optional(), pv: Pv, idToken: IdToken, platform: Platform }),
73
74
  // Host sets/changes their display name AFTER createRoom (for anonymous one-tap
74
75
  // hosts who started nameless). Host-only; the relay re-broadcasts the lobby.
75
76
  import_zod.z.object({ t: import_zod.z.literal("renameHost"), name: DisplayName }),
76
- import_zod.z.object({ t: import_zod.z.literal("joinRoom"), code: RoomCode, name: DisplayName, avatar: Avatar.optional(), pv: Pv, idToken: IdToken }),
77
- import_zod.z.object({ t: import_zod.z.literal("resume"), code: RoomCode, token: import_zod.z.string().max(120), avatar: Avatar.optional(), pv: Pv, idToken: IdToken }),
77
+ import_zod.z.object({ t: import_zod.z.literal("joinRoom"), code: RoomCode, name: DisplayName, avatar: Avatar.optional(), pv: Pv, idToken: IdToken, platform: Platform }),
78
+ import_zod.z.object({ t: import_zod.z.literal("resume"), code: RoomCode, token: import_zod.z.string().max(120), avatar: Avatar.optional(), pv: Pv, idToken: IdToken, platform: Platform }),
78
79
  import_zod.z.object({ t: import_zod.z.literal("leaveRoom") }),
79
80
  import_zod.z.object({ t: import_zod.z.literal("approve"), playerId: PlayerId }),
80
81
  import_zod.z.object({ t: import_zod.z.literal("reject"), playerId: PlayerId }),
@@ -86,6 +87,10 @@ var ClientMsg = import_zod.z.discriminatedUnion("t", [
86
87
  import_zod.z.object({ t: import_zod.z.literal("setTeams"), teams: import_zod.z.array(DisplayName).min(1).max(LIMITS.MAX_PLAYERS) }),
87
88
  // A player joins team slot `teamIndex` (0-based, into the host's `setTeams` list).
88
89
  import_zod.z.object({ t: import_zod.z.literal("pickTeam"), teamIndex: import_zod.z.number().int().min(0).max(LIMITS.MAX_PLAYERS - 1) }),
90
+ // Host's IN-PROGRESS mode selection in the lobby — a live preview so waiting players see which mode
91
+ // is coming before start. Distinct from startGame.modeId (which commits it); the relay defaults
92
+ // startGame to this when modeId is omitted. Re-broadcasts the lobby.
93
+ import_zod.z.object({ t: import_zod.z.literal("setMode"), modeId: import_zod.z.enum(MODE_IDS) }),
89
94
  // Host signals it's busy configuring the game (categories/rounds/mode) so waiting players can show
90
95
  // a "host is setting up…" state instead of a frozen-looking lobby. 'idle' when the settings close.
91
96
  import_zod.z.object({ t: import_zod.z.literal("hostActivity"), activity: import_zod.z.enum(["configuring", "idle"]) }),
package/dist/index.d.cts CHANGED
@@ -75,6 +75,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
75
75
  }>>;
76
76
  pv: z.ZodOptional<z.ZodNumber>;
77
77
  idToken: z.ZodOptional<z.ZodString>;
78
+ platform: z.ZodOptional<z.ZodEnum<["web", "ios", "android"]>>;
78
79
  }, "strip", z.ZodTypeAny, {
79
80
  t: "createRoom";
80
81
  name?: string | undefined;
@@ -84,6 +85,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
84
85
  } | undefined;
85
86
  pv?: number | undefined;
86
87
  idToken?: string | undefined;
88
+ platform?: "web" | "ios" | "android" | undefined;
87
89
  }, {
88
90
  t: "createRoom";
89
91
  name?: string | undefined;
@@ -93,6 +95,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
93
95
  } | undefined;
94
96
  pv?: number | undefined;
95
97
  idToken?: string | undefined;
98
+ platform?: "web" | "ios" | "android" | undefined;
96
99
  }>, z.ZodObject<{
97
100
  t: z.ZodLiteral<"renameHost">;
98
101
  name: z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>;
@@ -118,6 +121,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
118
121
  }>>;
119
122
  pv: z.ZodOptional<z.ZodNumber>;
120
123
  idToken: z.ZodOptional<z.ZodString>;
124
+ platform: z.ZodOptional<z.ZodEnum<["web", "ios", "android"]>>;
121
125
  }, "strip", z.ZodTypeAny, {
122
126
  code: string;
123
127
  t: "joinRoom";
@@ -128,6 +132,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
128
132
  } | undefined;
129
133
  pv?: number | undefined;
130
134
  idToken?: string | undefined;
135
+ platform?: "web" | "ios" | "android" | undefined;
131
136
  }, {
132
137
  code: string;
133
138
  t: "joinRoom";
@@ -138,6 +143,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
138
143
  } | undefined;
139
144
  pv?: number | undefined;
140
145
  idToken?: string | undefined;
146
+ platform?: "web" | "ios" | "android" | undefined;
141
147
  }>, z.ZodObject<{
142
148
  t: z.ZodLiteral<"resume">;
143
149
  code: z.ZodString;
@@ -154,6 +160,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
154
160
  }>>;
155
161
  pv: z.ZodOptional<z.ZodNumber>;
156
162
  idToken: z.ZodOptional<z.ZodString>;
163
+ platform: z.ZodOptional<z.ZodEnum<["web", "ios", "android"]>>;
157
164
  }, "strip", z.ZodTypeAny, {
158
165
  code: string;
159
166
  t: "resume";
@@ -164,6 +171,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
164
171
  } | undefined;
165
172
  pv?: number | undefined;
166
173
  idToken?: string | undefined;
174
+ platform?: "web" | "ios" | "android" | undefined;
167
175
  }, {
168
176
  code: string;
169
177
  t: "resume";
@@ -174,6 +182,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
174
182
  } | undefined;
175
183
  pv?: number | undefined;
176
184
  idToken?: string | undefined;
185
+ platform?: "web" | "ios" | "android" | undefined;
177
186
  }>, z.ZodObject<{
178
187
  t: z.ZodLiteral<"leaveRoom">;
179
188
  }, "strip", z.ZodTypeAny, {
@@ -234,6 +243,15 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
234
243
  }, {
235
244
  t: "pickTeam";
236
245
  teamIndex: number;
246
+ }>, z.ZodObject<{
247
+ t: z.ZodLiteral<"setMode">;
248
+ modeId: z.ZodEnum<["solo", "oneDevice", "snag", "multiplayer"]>;
249
+ }, "strip", z.ZodTypeAny, {
250
+ t: "setMode";
251
+ modeId: "solo" | "oneDevice" | "snag" | "multiplayer";
252
+ }, {
253
+ t: "setMode";
254
+ modeId: "solo" | "oneDevice" | "snag" | "multiplayer";
237
255
  }>, z.ZodObject<{
238
256
  t: z.ZodLiteral<"hostActivity">;
239
257
  activity: z.ZodEnum<["configuring", "idle"]>;
@@ -255,16 +273,16 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
255
273
  t: "startGame";
256
274
  categoryIds: string[];
257
275
  totalRounds: number;
258
- game?: "trivia" | undefined;
259
276
  modeId?: "solo" | "oneDevice" | "snag" | "multiplayer" | undefined;
277
+ game?: "trivia" | undefined;
260
278
  buzzerMode?: "solo" | "off" | "race" | "controller" | undefined;
261
279
  noHost?: boolean | undefined;
262
280
  }, {
263
281
  t: "startGame";
264
282
  categoryIds: string[];
265
283
  totalRounds: number;
266
- game?: "trivia" | undefined;
267
284
  modeId?: "solo" | "oneDevice" | "snag" | "multiplayer" | undefined;
285
+ game?: "trivia" | undefined;
268
286
  buzzerMode?: "solo" | "off" | "race" | "controller" | undefined;
269
287
  noHost?: boolean | undefined;
270
288
  }>, z.ZodObject<{
@@ -406,6 +424,8 @@ interface CategoryView {
406
424
  packName: string;
407
425
  icon: string;
408
426
  hasImage: boolean;
427
+ /** Category's brand color (hex, e.g. '#E8473F') for board coloring; absent if the category has none. */
428
+ color?: string;
409
429
  }
410
430
  type GameStatus = 'setup' | 'categorySelection' | 'inProgress' | 'completed';
411
431
  type GameplayFlow = 'classic' | 'openJudged' | 'noHost' | 'buzzer';
@@ -425,11 +445,13 @@ interface TeamView {
425
445
  type: HelpName;
426
446
  isUsed: boolean;
427
447
  }[];
428
- /** The team's players in rotation order. Empty for host-run single-device teams. */
448
+ /** The team's players in rotation order (`connected` = that player's socket is online right now).
449
+ * Empty for host-run single-device teams. */
429
450
  players: {
430
451
  id: string;
431
452
  name: string;
432
453
  emoji: string;
454
+ connected: boolean;
433
455
  }[];
434
456
  /** The player on THIS team whose turn it is to answer (rotates each turn); null if the team has
435
457
  * no seated players. In controller mode only this player may `answer` on the team's turn. */
@@ -554,6 +576,7 @@ type ServerMsg = {
554
576
  selectedCategoryIds: string[];
555
577
  teams: TeamSlotView[];
556
578
  hostActivity: 'configuring' | 'idle';
579
+ modeId: ModeId | null;
557
580
  you: YouContext;
558
581
  } | {
559
582
  t: 'state';
@@ -566,6 +589,10 @@ type ServerMsg = {
566
589
  effects: Effect[];
567
590
  } | {
568
591
  t: 'reported';
592
+ } | {
593
+ t: 'serverNotice';
594
+ message: string;
595
+ restartInSec?: number;
569
596
  } | {
570
597
  t: 'error';
571
598
  code: string;
package/dist/index.d.ts CHANGED
@@ -75,6 +75,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
75
75
  }>>;
76
76
  pv: z.ZodOptional<z.ZodNumber>;
77
77
  idToken: z.ZodOptional<z.ZodString>;
78
+ platform: z.ZodOptional<z.ZodEnum<["web", "ios", "android"]>>;
78
79
  }, "strip", z.ZodTypeAny, {
79
80
  t: "createRoom";
80
81
  name?: string | undefined;
@@ -84,6 +85,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
84
85
  } | undefined;
85
86
  pv?: number | undefined;
86
87
  idToken?: string | undefined;
88
+ platform?: "web" | "ios" | "android" | undefined;
87
89
  }, {
88
90
  t: "createRoom";
89
91
  name?: string | undefined;
@@ -93,6 +95,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
93
95
  } | undefined;
94
96
  pv?: number | undefined;
95
97
  idToken?: string | undefined;
98
+ platform?: "web" | "ios" | "android" | undefined;
96
99
  }>, z.ZodObject<{
97
100
  t: z.ZodLiteral<"renameHost">;
98
101
  name: z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>;
@@ -118,6 +121,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
118
121
  }>>;
119
122
  pv: z.ZodOptional<z.ZodNumber>;
120
123
  idToken: z.ZodOptional<z.ZodString>;
124
+ platform: z.ZodOptional<z.ZodEnum<["web", "ios", "android"]>>;
121
125
  }, "strip", z.ZodTypeAny, {
122
126
  code: string;
123
127
  t: "joinRoom";
@@ -128,6 +132,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
128
132
  } | undefined;
129
133
  pv?: number | undefined;
130
134
  idToken?: string | undefined;
135
+ platform?: "web" | "ios" | "android" | undefined;
131
136
  }, {
132
137
  code: string;
133
138
  t: "joinRoom";
@@ -138,6 +143,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
138
143
  } | undefined;
139
144
  pv?: number | undefined;
140
145
  idToken?: string | undefined;
146
+ platform?: "web" | "ios" | "android" | undefined;
141
147
  }>, z.ZodObject<{
142
148
  t: z.ZodLiteral<"resume">;
143
149
  code: z.ZodString;
@@ -154,6 +160,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
154
160
  }>>;
155
161
  pv: z.ZodOptional<z.ZodNumber>;
156
162
  idToken: z.ZodOptional<z.ZodString>;
163
+ platform: z.ZodOptional<z.ZodEnum<["web", "ios", "android"]>>;
157
164
  }, "strip", z.ZodTypeAny, {
158
165
  code: string;
159
166
  t: "resume";
@@ -164,6 +171,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
164
171
  } | undefined;
165
172
  pv?: number | undefined;
166
173
  idToken?: string | undefined;
174
+ platform?: "web" | "ios" | "android" | undefined;
167
175
  }, {
168
176
  code: string;
169
177
  t: "resume";
@@ -174,6 +182,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
174
182
  } | undefined;
175
183
  pv?: number | undefined;
176
184
  idToken?: string | undefined;
185
+ platform?: "web" | "ios" | "android" | undefined;
177
186
  }>, z.ZodObject<{
178
187
  t: z.ZodLiteral<"leaveRoom">;
179
188
  }, "strip", z.ZodTypeAny, {
@@ -234,6 +243,15 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
234
243
  }, {
235
244
  t: "pickTeam";
236
245
  teamIndex: number;
246
+ }>, z.ZodObject<{
247
+ t: z.ZodLiteral<"setMode">;
248
+ modeId: z.ZodEnum<["solo", "oneDevice", "snag", "multiplayer"]>;
249
+ }, "strip", z.ZodTypeAny, {
250
+ t: "setMode";
251
+ modeId: "solo" | "oneDevice" | "snag" | "multiplayer";
252
+ }, {
253
+ t: "setMode";
254
+ modeId: "solo" | "oneDevice" | "snag" | "multiplayer";
237
255
  }>, z.ZodObject<{
238
256
  t: z.ZodLiteral<"hostActivity">;
239
257
  activity: z.ZodEnum<["configuring", "idle"]>;
@@ -255,16 +273,16 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
255
273
  t: "startGame";
256
274
  categoryIds: string[];
257
275
  totalRounds: number;
258
- game?: "trivia" | undefined;
259
276
  modeId?: "solo" | "oneDevice" | "snag" | "multiplayer" | undefined;
277
+ game?: "trivia" | undefined;
260
278
  buzzerMode?: "solo" | "off" | "race" | "controller" | undefined;
261
279
  noHost?: boolean | undefined;
262
280
  }, {
263
281
  t: "startGame";
264
282
  categoryIds: string[];
265
283
  totalRounds: number;
266
- game?: "trivia" | undefined;
267
284
  modeId?: "solo" | "oneDevice" | "snag" | "multiplayer" | undefined;
285
+ game?: "trivia" | undefined;
268
286
  buzzerMode?: "solo" | "off" | "race" | "controller" | undefined;
269
287
  noHost?: boolean | undefined;
270
288
  }>, z.ZodObject<{
@@ -406,6 +424,8 @@ interface CategoryView {
406
424
  packName: string;
407
425
  icon: string;
408
426
  hasImage: boolean;
427
+ /** Category's brand color (hex, e.g. '#E8473F') for board coloring; absent if the category has none. */
428
+ color?: string;
409
429
  }
410
430
  type GameStatus = 'setup' | 'categorySelection' | 'inProgress' | 'completed';
411
431
  type GameplayFlow = 'classic' | 'openJudged' | 'noHost' | 'buzzer';
@@ -425,11 +445,13 @@ interface TeamView {
425
445
  type: HelpName;
426
446
  isUsed: boolean;
427
447
  }[];
428
- /** The team's players in rotation order. Empty for host-run single-device teams. */
448
+ /** The team's players in rotation order (`connected` = that player's socket is online right now).
449
+ * Empty for host-run single-device teams. */
429
450
  players: {
430
451
  id: string;
431
452
  name: string;
432
453
  emoji: string;
454
+ connected: boolean;
433
455
  }[];
434
456
  /** The player on THIS team whose turn it is to answer (rotates each turn); null if the team has
435
457
  * no seated players. In controller mode only this player may `answer` on the team's turn. */
@@ -554,6 +576,7 @@ type ServerMsg = {
554
576
  selectedCategoryIds: string[];
555
577
  teams: TeamSlotView[];
556
578
  hostActivity: 'configuring' | 'idle';
579
+ modeId: ModeId | null;
557
580
  you: YouContext;
558
581
  } | {
559
582
  t: 'state';
@@ -566,6 +589,10 @@ type ServerMsg = {
566
589
  effects: Effect[];
567
590
  } | {
568
591
  t: 'reported';
592
+ } | {
593
+ t: 'serverNotice';
594
+ message: string;
595
+ restartInSec?: number;
569
596
  } | {
570
597
  t: 'error';
571
598
  code: string;
package/dist/index.js CHANGED
@@ -32,18 +32,19 @@ var HelpType = z.enum([
32
32
  ]);
33
33
  var Pv = z.number().int().min(1).max(1e6).optional();
34
34
  var IdToken = z.string().max(4096).optional();
35
+ var Platform = z.enum(["web", "ios", "android"]).optional();
35
36
  var Avatar = z.object({
36
37
  emoji: z.string().min(1).max(16).transform((s) => s.replace(UNSAFE_CHARS, "")).refine((s) => s.length >= 1, "empty emoji"),
37
38
  color: z.string().regex(/^#[0-9a-fA-F]{6}$/, "color must be #rrggbb")
38
39
  });
39
40
  var ClientMsg = z.discriminatedUnion("t", [
40
41
  // room / lobby
41
- z.object({ t: z.literal("createRoom"), name: DisplayName.optional(), avatar: Avatar.optional(), pv: Pv, idToken: IdToken }),
42
+ z.object({ t: z.literal("createRoom"), name: DisplayName.optional(), avatar: Avatar.optional(), pv: Pv, idToken: IdToken, platform: Platform }),
42
43
  // Host sets/changes their display name AFTER createRoom (for anonymous one-tap
43
44
  // hosts who started nameless). Host-only; the relay re-broadcasts the lobby.
44
45
  z.object({ t: z.literal("renameHost"), name: DisplayName }),
45
- z.object({ t: z.literal("joinRoom"), code: RoomCode, name: DisplayName, avatar: Avatar.optional(), pv: Pv, idToken: IdToken }),
46
- z.object({ t: z.literal("resume"), code: RoomCode, token: z.string().max(120), avatar: Avatar.optional(), pv: Pv, idToken: IdToken }),
46
+ z.object({ t: z.literal("joinRoom"), code: RoomCode, name: DisplayName, avatar: Avatar.optional(), pv: Pv, idToken: IdToken, platform: Platform }),
47
+ z.object({ t: z.literal("resume"), code: RoomCode, token: z.string().max(120), avatar: Avatar.optional(), pv: Pv, idToken: IdToken, platform: Platform }),
47
48
  z.object({ t: z.literal("leaveRoom") }),
48
49
  z.object({ t: z.literal("approve"), playerId: PlayerId }),
49
50
  z.object({ t: z.literal("reject"), playerId: PlayerId }),
@@ -55,6 +56,10 @@ var ClientMsg = z.discriminatedUnion("t", [
55
56
  z.object({ t: z.literal("setTeams"), teams: z.array(DisplayName).min(1).max(LIMITS.MAX_PLAYERS) }),
56
57
  // A player joins team slot `teamIndex` (0-based, into the host's `setTeams` list).
57
58
  z.object({ t: z.literal("pickTeam"), teamIndex: z.number().int().min(0).max(LIMITS.MAX_PLAYERS - 1) }),
59
+ // Host's IN-PROGRESS mode selection in the lobby — a live preview so waiting players see which mode
60
+ // is coming before start. Distinct from startGame.modeId (which commits it); the relay defaults
61
+ // startGame to this when modeId is omitted. Re-broadcasts the lobby.
62
+ z.object({ t: z.literal("setMode"), modeId: z.enum(MODE_IDS) }),
58
63
  // Host signals it's busy configuring the game (categories/rounds/mode) so waiting players can show
59
64
  // a "host is setting up…" state instead of a frozen-looking lobby. 'idle' when the settings close.
60
65
  z.object({ t: z.literal("hostActivity"), activity: z.enum(["configuring", "idle"]) }),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thegeem/protocol",
3
- "version": "0.1.10",
3
+ "version": "0.1.12",
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",