@thegeem/protocol 0.1.33 → 0.1.35
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 +4 -3
- package/dist/index.d.cts +41 -1
- package/dist/index.d.ts +41 -1
- package/dist/index.js +4 -3
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -90,6 +90,7 @@ var HelpType = import_zod.z.enum([
|
|
|
90
90
|
var Pv = import_zod.z.number().int().min(1).max(1e6).optional();
|
|
91
91
|
var IdToken = import_zod.z.string().max(4096).optional();
|
|
92
92
|
var Platform = import_zod.z.enum(["web", "ios", "android"]).optional();
|
|
93
|
+
var AppVersion = import_zod.z.string().trim().max(24).regex(/^[0-9]+(\.[0-9]+){0,3}([-+][0-9A-Za-z.-]+)?$/, "bad app version").optional();
|
|
93
94
|
var Avatar = import_zod.z.object({
|
|
94
95
|
emoji: import_zod.z.string().min(1).max(16).transform((s) => s.replace(UNSAFE_CHARS, "")).refine((s) => s.length >= 1, "empty emoji"),
|
|
95
96
|
color: import_zod.z.string().regex(/^#[0-9a-fA-F]{6}$/, "color must be #rrggbb")
|
|
@@ -97,7 +98,7 @@ var Avatar = import_zod.z.object({
|
|
|
97
98
|
var Character = import_zod.z.enum(CHARACTER_IDS);
|
|
98
99
|
var ClientMsg = import_zod.z.discriminatedUnion("t", [
|
|
99
100
|
// room / lobby
|
|
100
|
-
import_zod.z.object({ t: import_zod.z.literal("createRoom"), name: DisplayName.optional(), avatar: Avatar.optional(), game: import_zod.z.enum(GAME_IDS).optional(), character: Character.optional(), pv: Pv, idToken: IdToken, platform: Platform }),
|
|
101
|
+
import_zod.z.object({ t: import_zod.z.literal("createRoom"), name: DisplayName.optional(), avatar: Avatar.optional(), game: import_zod.z.enum(GAME_IDS).optional(), character: Character.optional(), pv: Pv, idToken: IdToken, platform: Platform, appVersion: AppVersion }),
|
|
101
102
|
// Host sets/changes their display name AFTER createRoom (for anonymous one-tap
|
|
102
103
|
// hosts who started nameless). Host-only; the relay re-broadcasts the lobby.
|
|
103
104
|
// SUPERSEDED by setProfile (kept working for shipped builds).
|
|
@@ -111,8 +112,8 @@ var ClientMsg = import_zod.z.discriminatedUnion("t", [
|
|
|
111
112
|
// view carries names+avatars so it updates live; dama/ersimha views are id-keyed (clients
|
|
112
113
|
// map ids→names from the lobby roster), so a change there lands on the next lobby.
|
|
113
114
|
import_zod.z.object({ t: import_zod.z.literal("setProfile"), name: DisplayName.optional(), avatar: Avatar.optional(), character: Character.optional() }),
|
|
114
|
-
import_zod.z.object({ t: import_zod.z.literal("joinRoom"), code: RoomCode, name: DisplayName, avatar: Avatar.optional(), character: Character.optional(), pv: Pv, idToken: IdToken, platform: Platform }),
|
|
115
|
-
import_zod.z.object({ t: import_zod.z.literal("resume"), code: RoomCode, token: import_zod.z.string().max(120), avatar: Avatar.optional(), character: Character.optional(), pv: Pv, idToken: IdToken, platform: Platform }),
|
|
115
|
+
import_zod.z.object({ t: import_zod.z.literal("joinRoom"), code: RoomCode, name: DisplayName, avatar: Avatar.optional(), character: Character.optional(), pv: Pv, idToken: IdToken, platform: Platform, appVersion: AppVersion }),
|
|
116
|
+
import_zod.z.object({ t: import_zod.z.literal("resume"), code: RoomCode, token: import_zod.z.string().max(120), avatar: Avatar.optional(), character: Character.optional(), pv: Pv, idToken: IdToken, platform: Platform, appVersion: AppVersion }),
|
|
116
117
|
// `tally` (gs#46) = wins per PLAYER across every game this room has played tonight — «نتيجة الليلة».
|
|
117
118
|
// Keyed by playerId, NOT by team: team names are recycled each game, so a per-team count means nothing
|
|
118
119
|
// across a night. Survives playAgain. A One Device game credits nobody (its team slots hold no players).
|
package/dist/index.d.cts
CHANGED
|
@@ -122,6 +122,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
|
|
|
122
122
|
pv: z.ZodOptional<z.ZodNumber>;
|
|
123
123
|
idToken: z.ZodOptional<z.ZodString>;
|
|
124
124
|
platform: z.ZodOptional<z.ZodEnum<["web", "ios", "android"]>>;
|
|
125
|
+
appVersion: z.ZodOptional<z.ZodString>;
|
|
125
126
|
}, "strip", z.ZodTypeAny, {
|
|
126
127
|
t: "createRoom";
|
|
127
128
|
name?: string | undefined;
|
|
@@ -134,6 +135,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
|
|
|
134
135
|
pv?: number | undefined;
|
|
135
136
|
idToken?: string | undefined;
|
|
136
137
|
platform?: "web" | "ios" | "android" | undefined;
|
|
138
|
+
appVersion?: string | undefined;
|
|
137
139
|
}, {
|
|
138
140
|
t: "createRoom";
|
|
139
141
|
name?: string | undefined;
|
|
@@ -146,6 +148,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
|
|
|
146
148
|
pv?: number | undefined;
|
|
147
149
|
idToken?: string | undefined;
|
|
148
150
|
platform?: "web" | "ios" | "android" | undefined;
|
|
151
|
+
appVersion?: string | undefined;
|
|
149
152
|
}>, z.ZodObject<{
|
|
150
153
|
t: z.ZodLiteral<"renameHost">;
|
|
151
154
|
name: z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>;
|
|
@@ -203,6 +206,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
|
|
|
203
206
|
pv: z.ZodOptional<z.ZodNumber>;
|
|
204
207
|
idToken: z.ZodOptional<z.ZodString>;
|
|
205
208
|
platform: z.ZodOptional<z.ZodEnum<["web", "ios", "android"]>>;
|
|
209
|
+
appVersion: z.ZodOptional<z.ZodString>;
|
|
206
210
|
}, "strip", z.ZodTypeAny, {
|
|
207
211
|
code: string;
|
|
208
212
|
t: "joinRoom";
|
|
@@ -215,6 +219,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
|
|
|
215
219
|
pv?: number | undefined;
|
|
216
220
|
idToken?: string | undefined;
|
|
217
221
|
platform?: "web" | "ios" | "android" | undefined;
|
|
222
|
+
appVersion?: string | undefined;
|
|
218
223
|
}, {
|
|
219
224
|
code: string;
|
|
220
225
|
t: "joinRoom";
|
|
@@ -227,6 +232,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
|
|
|
227
232
|
pv?: number | undefined;
|
|
228
233
|
idToken?: string | undefined;
|
|
229
234
|
platform?: "web" | "ios" | "android" | undefined;
|
|
235
|
+
appVersion?: string | undefined;
|
|
230
236
|
}>, z.ZodObject<{
|
|
231
237
|
t: z.ZodLiteral<"resume">;
|
|
232
238
|
code: z.ZodString;
|
|
@@ -245,6 +251,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
|
|
|
245
251
|
pv: z.ZodOptional<z.ZodNumber>;
|
|
246
252
|
idToken: z.ZodOptional<z.ZodString>;
|
|
247
253
|
platform: z.ZodOptional<z.ZodEnum<["web", "ios", "android"]>>;
|
|
254
|
+
appVersion: z.ZodOptional<z.ZodString>;
|
|
248
255
|
}, "strip", z.ZodTypeAny, {
|
|
249
256
|
code: string;
|
|
250
257
|
t: "resume";
|
|
@@ -257,6 +264,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
|
|
|
257
264
|
pv?: number | undefined;
|
|
258
265
|
idToken?: string | undefined;
|
|
259
266
|
platform?: "web" | "ios" | "android" | undefined;
|
|
267
|
+
appVersion?: string | undefined;
|
|
260
268
|
}, {
|
|
261
269
|
code: string;
|
|
262
270
|
t: "resume";
|
|
@@ -269,6 +277,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
|
|
|
269
277
|
pv?: number | undefined;
|
|
270
278
|
idToken?: string | undefined;
|
|
271
279
|
platform?: "web" | "ios" | "android" | undefined;
|
|
280
|
+
appVersion?: string | undefined;
|
|
272
281
|
}>, z.ZodObject<{
|
|
273
282
|
t: z.ZodLiteral<"setPlaying">;
|
|
274
283
|
playerId: z.ZodOptional<z.ZodString>;
|
|
@@ -683,6 +692,34 @@ interface LobbyPlayer {
|
|
|
683
692
|
/** Team index once the game has started; null/absent in the lobby. */
|
|
684
693
|
teamIndex?: number | null;
|
|
685
694
|
}
|
|
695
|
+
/**
|
|
696
|
+
* Who is in the room, carried ON the game-state push (gs#71).
|
|
697
|
+
*
|
|
698
|
+
* `players[]` in the `lobby` frame is the only other carrier of names, and the lobby does not go out
|
|
699
|
+
* mid-game — deliberately, since a stray `lobby` under a running game bounces clients off their board
|
|
700
|
+
* (the gs#49 class). So a client that refreshed mid-game had NO roster for the rest of the game, and
|
|
701
|
+
* every id→name lookup degraded to whatever that client happened to use as its null-fallback: «؟» on
|
|
702
|
+
* web, the colour name in دامة on Android (readable by luck), and an empty string in ارسمها (a sentence
|
|
703
|
+
* with a hole in it).
|
|
704
|
+
*
|
|
705
|
+
* It rides ON the state message rather than arriving as a separate frame because both consuming teams
|
|
706
|
+
* asked for that independently, for the same reason: a roster in its own message can land either side
|
|
707
|
+
* of the state push, giving one render with names and one without on clients that redraw per state.
|
|
708
|
+
* Bundled, it cannot race.
|
|
709
|
+
*
|
|
710
|
+
* Unlike `LobbyPlayer` this INCLUDES THE HOST (`isHost`), who is filtered out of `lobby.players` by
|
|
711
|
+
* design and therefore has no row — yet needs a face wherever the host can appear, e.g. the `tally`.
|
|
712
|
+
*/
|
|
713
|
+
interface RosterEntry {
|
|
714
|
+
id: string;
|
|
715
|
+
name: string;
|
|
716
|
+
/** Privacy-safe avatar (emoji + color); absent if unset. */
|
|
717
|
+
avatar?: AvatarView;
|
|
718
|
+
/** True for the room's host, who has no row in `lobby.players`. */
|
|
719
|
+
isHost?: boolean;
|
|
720
|
+
/** Is this person currently connected? Mirrors `LobbyPlayer.connected`. */
|
|
721
|
+
connected?: boolean;
|
|
722
|
+
}
|
|
686
723
|
/** Per-recipient context attached to lobby/state pushes. */
|
|
687
724
|
interface YouContext {
|
|
688
725
|
id: string;
|
|
@@ -945,16 +982,19 @@ type ServerMsg = {
|
|
|
945
982
|
view: GameStateView;
|
|
946
983
|
you: YouContext;
|
|
947
984
|
teamConnected: boolean[];
|
|
985
|
+
roster?: RosterEntry[];
|
|
948
986
|
} | {
|
|
949
987
|
t: 'damaState';
|
|
950
988
|
gameId: 'dama';
|
|
951
989
|
view: DamaStateView;
|
|
952
990
|
you: YouContext;
|
|
991
|
+
roster?: RosterEntry[];
|
|
953
992
|
} | {
|
|
954
993
|
t: 'ersimhaState';
|
|
955
994
|
gameId: 'ersimha';
|
|
956
995
|
view: ErsimhaStateView;
|
|
957
996
|
you: YouContext;
|
|
997
|
+
roster?: RosterEntry[];
|
|
958
998
|
} | {
|
|
959
999
|
t: 'strokeBatch';
|
|
960
1000
|
from: string;
|
|
@@ -986,4 +1026,4 @@ type ServerMsg = {
|
|
|
986
1026
|
message: string;
|
|
987
1027
|
};
|
|
988
1028
|
|
|
989
|
-
export { type AvatarView, type BuzzerGameMode, CHARACTER_IDS, type CategoryView, type CharacterId, ClientMsg, type DamaMoveView, type DamaPieceView, type DamaStateView, EMOTE_IDS, type Effect, type EmoteId, type ErsimhaStateView, GAMES, GAME_IDS, type GameId, type GameInfo, type GameStateView, type GameStatus, type GameplayFlow, type HelpName, LIMITS, type LobbyPlayer, MIN_SUPPORTED_PV, MODES, MODE_IDS, type ModeId, type ModeInfo, PROTOCOL_VERSION, type QuestionView, ROOM_ALPHABET, type ServerMsg, type SoundName, type StrokePointView, type TeamSlotView, type TeamView, type YouContext, gameIdForPv, gamesForPv, modesForGame };
|
|
1029
|
+
export { type AvatarView, type BuzzerGameMode, CHARACTER_IDS, type CategoryView, type CharacterId, ClientMsg, type DamaMoveView, type DamaPieceView, type DamaStateView, EMOTE_IDS, type Effect, type EmoteId, type ErsimhaStateView, GAMES, GAME_IDS, type GameId, type GameInfo, type GameStateView, type GameStatus, type GameplayFlow, type HelpName, LIMITS, type LobbyPlayer, MIN_SUPPORTED_PV, MODES, MODE_IDS, type ModeId, type ModeInfo, PROTOCOL_VERSION, type QuestionView, ROOM_ALPHABET, type RosterEntry, type ServerMsg, type SoundName, type StrokePointView, type TeamSlotView, type TeamView, type YouContext, gameIdForPv, gamesForPv, modesForGame };
|
package/dist/index.d.ts
CHANGED
|
@@ -122,6 +122,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
|
|
|
122
122
|
pv: z.ZodOptional<z.ZodNumber>;
|
|
123
123
|
idToken: z.ZodOptional<z.ZodString>;
|
|
124
124
|
platform: z.ZodOptional<z.ZodEnum<["web", "ios", "android"]>>;
|
|
125
|
+
appVersion: z.ZodOptional<z.ZodString>;
|
|
125
126
|
}, "strip", z.ZodTypeAny, {
|
|
126
127
|
t: "createRoom";
|
|
127
128
|
name?: string | undefined;
|
|
@@ -134,6 +135,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
|
|
|
134
135
|
pv?: number | undefined;
|
|
135
136
|
idToken?: string | undefined;
|
|
136
137
|
platform?: "web" | "ios" | "android" | undefined;
|
|
138
|
+
appVersion?: string | undefined;
|
|
137
139
|
}, {
|
|
138
140
|
t: "createRoom";
|
|
139
141
|
name?: string | undefined;
|
|
@@ -146,6 +148,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
|
|
|
146
148
|
pv?: number | undefined;
|
|
147
149
|
idToken?: string | undefined;
|
|
148
150
|
platform?: "web" | "ios" | "android" | undefined;
|
|
151
|
+
appVersion?: string | undefined;
|
|
149
152
|
}>, z.ZodObject<{
|
|
150
153
|
t: z.ZodLiteral<"renameHost">;
|
|
151
154
|
name: z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>;
|
|
@@ -203,6 +206,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
|
|
|
203
206
|
pv: z.ZodOptional<z.ZodNumber>;
|
|
204
207
|
idToken: z.ZodOptional<z.ZodString>;
|
|
205
208
|
platform: z.ZodOptional<z.ZodEnum<["web", "ios", "android"]>>;
|
|
209
|
+
appVersion: z.ZodOptional<z.ZodString>;
|
|
206
210
|
}, "strip", z.ZodTypeAny, {
|
|
207
211
|
code: string;
|
|
208
212
|
t: "joinRoom";
|
|
@@ -215,6 +219,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
|
|
|
215
219
|
pv?: number | undefined;
|
|
216
220
|
idToken?: string | undefined;
|
|
217
221
|
platform?: "web" | "ios" | "android" | undefined;
|
|
222
|
+
appVersion?: string | undefined;
|
|
218
223
|
}, {
|
|
219
224
|
code: string;
|
|
220
225
|
t: "joinRoom";
|
|
@@ -227,6 +232,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
|
|
|
227
232
|
pv?: number | undefined;
|
|
228
233
|
idToken?: string | undefined;
|
|
229
234
|
platform?: "web" | "ios" | "android" | undefined;
|
|
235
|
+
appVersion?: string | undefined;
|
|
230
236
|
}>, z.ZodObject<{
|
|
231
237
|
t: z.ZodLiteral<"resume">;
|
|
232
238
|
code: z.ZodString;
|
|
@@ -245,6 +251,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
|
|
|
245
251
|
pv: z.ZodOptional<z.ZodNumber>;
|
|
246
252
|
idToken: z.ZodOptional<z.ZodString>;
|
|
247
253
|
platform: z.ZodOptional<z.ZodEnum<["web", "ios", "android"]>>;
|
|
254
|
+
appVersion: z.ZodOptional<z.ZodString>;
|
|
248
255
|
}, "strip", z.ZodTypeAny, {
|
|
249
256
|
code: string;
|
|
250
257
|
t: "resume";
|
|
@@ -257,6 +264,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
|
|
|
257
264
|
pv?: number | undefined;
|
|
258
265
|
idToken?: string | undefined;
|
|
259
266
|
platform?: "web" | "ios" | "android" | undefined;
|
|
267
|
+
appVersion?: string | undefined;
|
|
260
268
|
}, {
|
|
261
269
|
code: string;
|
|
262
270
|
t: "resume";
|
|
@@ -269,6 +277,7 @@ declare const ClientMsg: z.ZodDiscriminatedUnion<"t", [z.ZodObject<{
|
|
|
269
277
|
pv?: number | undefined;
|
|
270
278
|
idToken?: string | undefined;
|
|
271
279
|
platform?: "web" | "ios" | "android" | undefined;
|
|
280
|
+
appVersion?: string | undefined;
|
|
272
281
|
}>, z.ZodObject<{
|
|
273
282
|
t: z.ZodLiteral<"setPlaying">;
|
|
274
283
|
playerId: z.ZodOptional<z.ZodString>;
|
|
@@ -683,6 +692,34 @@ interface LobbyPlayer {
|
|
|
683
692
|
/** Team index once the game has started; null/absent in the lobby. */
|
|
684
693
|
teamIndex?: number | null;
|
|
685
694
|
}
|
|
695
|
+
/**
|
|
696
|
+
* Who is in the room, carried ON the game-state push (gs#71).
|
|
697
|
+
*
|
|
698
|
+
* `players[]` in the `lobby` frame is the only other carrier of names, and the lobby does not go out
|
|
699
|
+
* mid-game — deliberately, since a stray `lobby` under a running game bounces clients off their board
|
|
700
|
+
* (the gs#49 class). So a client that refreshed mid-game had NO roster for the rest of the game, and
|
|
701
|
+
* every id→name lookup degraded to whatever that client happened to use as its null-fallback: «؟» on
|
|
702
|
+
* web, the colour name in دامة on Android (readable by luck), and an empty string in ارسمها (a sentence
|
|
703
|
+
* with a hole in it).
|
|
704
|
+
*
|
|
705
|
+
* It rides ON the state message rather than arriving as a separate frame because both consuming teams
|
|
706
|
+
* asked for that independently, for the same reason: a roster in its own message can land either side
|
|
707
|
+
* of the state push, giving one render with names and one without on clients that redraw per state.
|
|
708
|
+
* Bundled, it cannot race.
|
|
709
|
+
*
|
|
710
|
+
* Unlike `LobbyPlayer` this INCLUDES THE HOST (`isHost`), who is filtered out of `lobby.players` by
|
|
711
|
+
* design and therefore has no row — yet needs a face wherever the host can appear, e.g. the `tally`.
|
|
712
|
+
*/
|
|
713
|
+
interface RosterEntry {
|
|
714
|
+
id: string;
|
|
715
|
+
name: string;
|
|
716
|
+
/** Privacy-safe avatar (emoji + color); absent if unset. */
|
|
717
|
+
avatar?: AvatarView;
|
|
718
|
+
/** True for the room's host, who has no row in `lobby.players`. */
|
|
719
|
+
isHost?: boolean;
|
|
720
|
+
/** Is this person currently connected? Mirrors `LobbyPlayer.connected`. */
|
|
721
|
+
connected?: boolean;
|
|
722
|
+
}
|
|
686
723
|
/** Per-recipient context attached to lobby/state pushes. */
|
|
687
724
|
interface YouContext {
|
|
688
725
|
id: string;
|
|
@@ -945,16 +982,19 @@ type ServerMsg = {
|
|
|
945
982
|
view: GameStateView;
|
|
946
983
|
you: YouContext;
|
|
947
984
|
teamConnected: boolean[];
|
|
985
|
+
roster?: RosterEntry[];
|
|
948
986
|
} | {
|
|
949
987
|
t: 'damaState';
|
|
950
988
|
gameId: 'dama';
|
|
951
989
|
view: DamaStateView;
|
|
952
990
|
you: YouContext;
|
|
991
|
+
roster?: RosterEntry[];
|
|
953
992
|
} | {
|
|
954
993
|
t: 'ersimhaState';
|
|
955
994
|
gameId: 'ersimha';
|
|
956
995
|
view: ErsimhaStateView;
|
|
957
996
|
you: YouContext;
|
|
997
|
+
roster?: RosterEntry[];
|
|
958
998
|
} | {
|
|
959
999
|
t: 'strokeBatch';
|
|
960
1000
|
from: string;
|
|
@@ -986,4 +1026,4 @@ type ServerMsg = {
|
|
|
986
1026
|
message: string;
|
|
987
1027
|
};
|
|
988
1028
|
|
|
989
|
-
export { type AvatarView, type BuzzerGameMode, CHARACTER_IDS, type CategoryView, type CharacterId, ClientMsg, type DamaMoveView, type DamaPieceView, type DamaStateView, EMOTE_IDS, type Effect, type EmoteId, type ErsimhaStateView, GAMES, GAME_IDS, type GameId, type GameInfo, type GameStateView, type GameStatus, type GameplayFlow, type HelpName, LIMITS, type LobbyPlayer, MIN_SUPPORTED_PV, MODES, MODE_IDS, type ModeId, type ModeInfo, PROTOCOL_VERSION, type QuestionView, ROOM_ALPHABET, type ServerMsg, type SoundName, type StrokePointView, type TeamSlotView, type TeamView, type YouContext, gameIdForPv, gamesForPv, modesForGame };
|
|
1029
|
+
export { type AvatarView, type BuzzerGameMode, CHARACTER_IDS, type CategoryView, type CharacterId, ClientMsg, type DamaMoveView, type DamaPieceView, type DamaStateView, EMOTE_IDS, type Effect, type EmoteId, type ErsimhaStateView, GAMES, GAME_IDS, type GameId, type GameInfo, type GameStateView, type GameStatus, type GameplayFlow, type HelpName, LIMITS, type LobbyPlayer, MIN_SUPPORTED_PV, MODES, MODE_IDS, type ModeId, type ModeInfo, PROTOCOL_VERSION, type QuestionView, ROOM_ALPHABET, type RosterEntry, type ServerMsg, type SoundName, type StrokePointView, type TeamSlotView, type TeamView, type YouContext, gameIdForPv, gamesForPv, modesForGame };
|
package/dist/index.js
CHANGED
|
@@ -53,6 +53,7 @@ var HelpType = z.enum([
|
|
|
53
53
|
var Pv = z.number().int().min(1).max(1e6).optional();
|
|
54
54
|
var IdToken = z.string().max(4096).optional();
|
|
55
55
|
var Platform = z.enum(["web", "ios", "android"]).optional();
|
|
56
|
+
var AppVersion = z.string().trim().max(24).regex(/^[0-9]+(\.[0-9]+){0,3}([-+][0-9A-Za-z.-]+)?$/, "bad app version").optional();
|
|
56
57
|
var Avatar = z.object({
|
|
57
58
|
emoji: z.string().min(1).max(16).transform((s) => s.replace(UNSAFE_CHARS, "")).refine((s) => s.length >= 1, "empty emoji"),
|
|
58
59
|
color: z.string().regex(/^#[0-9a-fA-F]{6}$/, "color must be #rrggbb")
|
|
@@ -60,7 +61,7 @@ var Avatar = z.object({
|
|
|
60
61
|
var Character = z.enum(CHARACTER_IDS);
|
|
61
62
|
var ClientMsg = z.discriminatedUnion("t", [
|
|
62
63
|
// room / lobby
|
|
63
|
-
z.object({ t: z.literal("createRoom"), name: DisplayName.optional(), avatar: Avatar.optional(), game: z.enum(GAME_IDS).optional(), character: Character.optional(), pv: Pv, idToken: IdToken, platform: Platform }),
|
|
64
|
+
z.object({ t: z.literal("createRoom"), name: DisplayName.optional(), avatar: Avatar.optional(), game: z.enum(GAME_IDS).optional(), character: Character.optional(), pv: Pv, idToken: IdToken, platform: Platform, appVersion: AppVersion }),
|
|
64
65
|
// Host sets/changes their display name AFTER createRoom (for anonymous one-tap
|
|
65
66
|
// hosts who started nameless). Host-only; the relay re-broadcasts the lobby.
|
|
66
67
|
// SUPERSEDED by setProfile (kept working for shipped builds).
|
|
@@ -74,8 +75,8 @@ var ClientMsg = z.discriminatedUnion("t", [
|
|
|
74
75
|
// view carries names+avatars so it updates live; dama/ersimha views are id-keyed (clients
|
|
75
76
|
// map ids→names from the lobby roster), so a change there lands on the next lobby.
|
|
76
77
|
z.object({ t: z.literal("setProfile"), name: DisplayName.optional(), avatar: Avatar.optional(), character: Character.optional() }),
|
|
77
|
-
z.object({ t: z.literal("joinRoom"), code: RoomCode, name: DisplayName, avatar: Avatar.optional(), character: Character.optional(), pv: Pv, idToken: IdToken, platform: Platform }),
|
|
78
|
-
z.object({ t: z.literal("resume"), code: RoomCode, token: z.string().max(120), avatar: Avatar.optional(), character: Character.optional(), pv: Pv, idToken: IdToken, platform: Platform }),
|
|
78
|
+
z.object({ t: z.literal("joinRoom"), code: RoomCode, name: DisplayName, avatar: Avatar.optional(), character: Character.optional(), pv: Pv, idToken: IdToken, platform: Platform, appVersion: AppVersion }),
|
|
79
|
+
z.object({ t: z.literal("resume"), code: RoomCode, token: z.string().max(120), avatar: Avatar.optional(), character: Character.optional(), pv: Pv, idToken: IdToken, platform: Platform, appVersion: AppVersion }),
|
|
79
80
|
// `tally` (gs#46) = wins per PLAYER across every game this room has played tonight — «نتيجة الليلة».
|
|
80
81
|
// Keyed by playerId, NOT by team: team names are recycled each game, so a per-team count means nothing
|
|
81
82
|
// across a night. Survives playAgain. A One Device game credits nobody (its team slots hold no players).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thegeem/protocol",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.35",
|
|
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",
|