@thegeem/protocol 0.1.34 → 0.1.36
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.d.cts +52 -1
- package/dist/index.d.ts +52 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -692,6 +692,34 @@ interface LobbyPlayer {
|
|
|
692
692
|
/** Team index once the game has started; null/absent in the lobby. */
|
|
693
693
|
teamIndex?: number | null;
|
|
694
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
|
+
}
|
|
695
723
|
/** Per-recipient context attached to lobby/state pushes. */
|
|
696
724
|
interface YouContext {
|
|
697
725
|
id: string;
|
|
@@ -710,6 +738,25 @@ interface CategoryView {
|
|
|
710
738
|
/** Category's brand color (hex, e.g. '#E8473F') for board coloring; absent if the category has none. */
|
|
711
739
|
color?: string;
|
|
712
740
|
}
|
|
741
|
+
/**
|
|
742
|
+
* A content pack — the grouping the category strip renders as a row (geem-server#76).
|
|
743
|
+
*
|
|
744
|
+
* **The ARRAY ORDER is the pack order.** That is the point of this type: pack order previously had no
|
|
745
|
+
* home on the wire, so all four clients derived it by first-seen from `categories[]` (Android's
|
|
746
|
+
* `onlineGroupedPacks`, iOS's `order: [String]`, and web/TV their own). Four derivations of one fact,
|
|
747
|
+
* and when the server's own category order turned out to be non-deterministic the strip reshuffled
|
|
748
|
+
* between visits (gs#74) with nothing on the wire to pin it. One ordered array replaces all four.
|
|
749
|
+
*
|
|
750
|
+
* Deliberately NO `sortOrder` field: an ordered array already carries the order, and a positional index
|
|
751
|
+
* beside it would be the same fact stored twice — which is exactly the drift argument that made
|
|
752
|
+
* `has_image` a boolean rather than a filename. Position cannot disagree with itself.
|
|
753
|
+
*/
|
|
754
|
+
interface PackView {
|
|
755
|
+
id: string;
|
|
756
|
+
name: string;
|
|
757
|
+
/** Does this pack have cover art at `/assets/cat/pack-<id>.png`? Absent until the admin field ships. */
|
|
758
|
+
hasImage?: boolean;
|
|
759
|
+
}
|
|
713
760
|
type GameStatus = 'setup' | 'categorySelection' | 'inProgress' | 'completed';
|
|
714
761
|
type GameplayFlow = 'classic' | 'openJudged' | 'noHost' | 'buzzer';
|
|
715
762
|
type BuzzerGameMode = 'off' | 'solo' | 'race' | 'controller';
|
|
@@ -940,6 +987,7 @@ type ServerMsg = {
|
|
|
940
987
|
hostPinned?: boolean;
|
|
941
988
|
players: LobbyPlayer[];
|
|
942
989
|
categories: CategoryView[];
|
|
990
|
+
packs?: PackView[];
|
|
943
991
|
selectedCategoryIds: string[];
|
|
944
992
|
teams: TeamSlotView[];
|
|
945
993
|
hostActivity: 'configuring' | 'idle';
|
|
@@ -954,16 +1002,19 @@ type ServerMsg = {
|
|
|
954
1002
|
view: GameStateView;
|
|
955
1003
|
you: YouContext;
|
|
956
1004
|
teamConnected: boolean[];
|
|
1005
|
+
roster?: RosterEntry[];
|
|
957
1006
|
} | {
|
|
958
1007
|
t: 'damaState';
|
|
959
1008
|
gameId: 'dama';
|
|
960
1009
|
view: DamaStateView;
|
|
961
1010
|
you: YouContext;
|
|
1011
|
+
roster?: RosterEntry[];
|
|
962
1012
|
} | {
|
|
963
1013
|
t: 'ersimhaState';
|
|
964
1014
|
gameId: 'ersimha';
|
|
965
1015
|
view: ErsimhaStateView;
|
|
966
1016
|
you: YouContext;
|
|
1017
|
+
roster?: RosterEntry[];
|
|
967
1018
|
} | {
|
|
968
1019
|
t: 'strokeBatch';
|
|
969
1020
|
from: string;
|
|
@@ -995,4 +1046,4 @@ type ServerMsg = {
|
|
|
995
1046
|
message: string;
|
|
996
1047
|
};
|
|
997
1048
|
|
|
998
|
-
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 };
|
|
1049
|
+
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 PackView, 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
|
@@ -692,6 +692,34 @@ interface LobbyPlayer {
|
|
|
692
692
|
/** Team index once the game has started; null/absent in the lobby. */
|
|
693
693
|
teamIndex?: number | null;
|
|
694
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
|
+
}
|
|
695
723
|
/** Per-recipient context attached to lobby/state pushes. */
|
|
696
724
|
interface YouContext {
|
|
697
725
|
id: string;
|
|
@@ -710,6 +738,25 @@ interface CategoryView {
|
|
|
710
738
|
/** Category's brand color (hex, e.g. '#E8473F') for board coloring; absent if the category has none. */
|
|
711
739
|
color?: string;
|
|
712
740
|
}
|
|
741
|
+
/**
|
|
742
|
+
* A content pack — the grouping the category strip renders as a row (geem-server#76).
|
|
743
|
+
*
|
|
744
|
+
* **The ARRAY ORDER is the pack order.** That is the point of this type: pack order previously had no
|
|
745
|
+
* home on the wire, so all four clients derived it by first-seen from `categories[]` (Android's
|
|
746
|
+
* `onlineGroupedPacks`, iOS's `order: [String]`, and web/TV their own). Four derivations of one fact,
|
|
747
|
+
* and when the server's own category order turned out to be non-deterministic the strip reshuffled
|
|
748
|
+
* between visits (gs#74) with nothing on the wire to pin it. One ordered array replaces all four.
|
|
749
|
+
*
|
|
750
|
+
* Deliberately NO `sortOrder` field: an ordered array already carries the order, and a positional index
|
|
751
|
+
* beside it would be the same fact stored twice — which is exactly the drift argument that made
|
|
752
|
+
* `has_image` a boolean rather than a filename. Position cannot disagree with itself.
|
|
753
|
+
*/
|
|
754
|
+
interface PackView {
|
|
755
|
+
id: string;
|
|
756
|
+
name: string;
|
|
757
|
+
/** Does this pack have cover art at `/assets/cat/pack-<id>.png`? Absent until the admin field ships. */
|
|
758
|
+
hasImage?: boolean;
|
|
759
|
+
}
|
|
713
760
|
type GameStatus = 'setup' | 'categorySelection' | 'inProgress' | 'completed';
|
|
714
761
|
type GameplayFlow = 'classic' | 'openJudged' | 'noHost' | 'buzzer';
|
|
715
762
|
type BuzzerGameMode = 'off' | 'solo' | 'race' | 'controller';
|
|
@@ -940,6 +987,7 @@ type ServerMsg = {
|
|
|
940
987
|
hostPinned?: boolean;
|
|
941
988
|
players: LobbyPlayer[];
|
|
942
989
|
categories: CategoryView[];
|
|
990
|
+
packs?: PackView[];
|
|
943
991
|
selectedCategoryIds: string[];
|
|
944
992
|
teams: TeamSlotView[];
|
|
945
993
|
hostActivity: 'configuring' | 'idle';
|
|
@@ -954,16 +1002,19 @@ type ServerMsg = {
|
|
|
954
1002
|
view: GameStateView;
|
|
955
1003
|
you: YouContext;
|
|
956
1004
|
teamConnected: boolean[];
|
|
1005
|
+
roster?: RosterEntry[];
|
|
957
1006
|
} | {
|
|
958
1007
|
t: 'damaState';
|
|
959
1008
|
gameId: 'dama';
|
|
960
1009
|
view: DamaStateView;
|
|
961
1010
|
you: YouContext;
|
|
1011
|
+
roster?: RosterEntry[];
|
|
962
1012
|
} | {
|
|
963
1013
|
t: 'ersimhaState';
|
|
964
1014
|
gameId: 'ersimha';
|
|
965
1015
|
view: ErsimhaStateView;
|
|
966
1016
|
you: YouContext;
|
|
1017
|
+
roster?: RosterEntry[];
|
|
967
1018
|
} | {
|
|
968
1019
|
t: 'strokeBatch';
|
|
969
1020
|
from: string;
|
|
@@ -995,4 +1046,4 @@ type ServerMsg = {
|
|
|
995
1046
|
message: string;
|
|
996
1047
|
};
|
|
997
1048
|
|
|
998
|
-
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 };
|
|
1049
|
+
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 PackView, type QuestionView, ROOM_ALPHABET, type RosterEntry, type ServerMsg, type SoundName, type StrokePointView, type TeamSlotView, type TeamView, type YouContext, gameIdForPv, gamesForPv, modesForGame };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thegeem/protocol",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.36",
|
|
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",
|