@magicworks/client-party-game 0.1.0-rc.5 → 0.1.0-rc.7
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/README.md +18 -3
- package/dist/client.d.ts +32 -67
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +180 -272
- package/dist/client.js.map +1 -1
- package/dist/connection.d.ts +159 -0
- package/dist/connection.d.ts.map +1 -0
- package/dist/connection.js +389 -0
- package/dist/connection.js.map +1 -0
- package/dist/protocol/codes.d.ts +33 -0
- package/dist/protocol/codes.d.ts.map +1 -0
- package/dist/protocol/codes.js +60 -0
- package/dist/protocol/codes.js.map +1 -0
- package/dist/protocol/events.d.ts +129 -0
- package/dist/protocol/events.d.ts.map +1 -0
- package/dist/protocol/events.js +131 -0
- package/dist/protocol/events.js.map +1 -0
- package/dist/protocol/index.d.ts +25 -0
- package/dist/protocol/index.d.ts.map +1 -0
- package/dist/protocol/index.js +41 -0
- package/dist/protocol/index.js.map +1 -0
- package/dist/protocol/limits.d.ts +40 -0
- package/dist/protocol/limits.d.ts.map +1 -0
- package/dist/protocol/limits.js +43 -0
- package/dist/protocol/limits.js.map +1 -0
- package/dist/protocol/messages.d.ts +308 -0
- package/dist/protocol/messages.d.ts.map +1 -0
- package/dist/protocol/messages.js +3 -0
- package/dist/protocol/messages.js.map +1 -0
- package/dist/protocol/placement.d.ts +83 -0
- package/dist/protocol/placement.d.ts.map +1 -0
- package/dist/protocol/placement.js +97 -0
- package/dist/protocol/placement.js.map +1 -0
- package/dist/protocol/routing.d.ts +26 -0
- package/dist/protocol/routing.d.ts.map +1 -0
- package/dist/protocol/routing.js +19 -0
- package/dist/protocol/routing.js.map +1 -0
- package/dist/protocol/scoring.d.ts +7 -0
- package/dist/protocol/scoring.d.ts.map +1 -0
- package/dist/protocol/scoring.js +13 -0
- package/dist/protocol/scoring.js.map +1 -0
- package/dist/protocol/speedtest.d.ts +9 -0
- package/dist/protocol/speedtest.d.ts.map +1 -0
- package/dist/protocol/speedtest.js +22 -0
- package/dist/protocol/speedtest.js.map +1 -0
- package/dist/socket.d.ts +4 -2
- package/dist/socket.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/protocol.d.ts +0 -519
- package/dist/protocol.d.ts.map +0 -1
- package/dist/protocol.js +0 -262
- package/dist/protocol.js.map +0 -1
package/README.md
CHANGED
|
@@ -10,8 +10,10 @@ Host TV client and wire protocol for the multiplayer party games (Name the Artis
|
|
|
10
10
|
|
|
11
11
|
- Opens, reopens and re-attaches to rooms, remembering the last room code so *Play again* within 20 minutes keeps the same phones
|
|
12
12
|
- Reaches a room in its own region: codes say which region holds them (`PARTY_REGIONS`), and with `regionUrls` the client connects for a code to that region's servers. Only opening a new room goes to the global, latency-routed `url`
|
|
13
|
-
-
|
|
14
|
-
-
|
|
13
|
+
- Asks where to connect before every socket (`GET /party/placement`, with the global `fetch` or the `fetch` option): for the room's code, which reaches the room's server, or for a new room, which reaches any server taking parties. The socket then carries that server's prefix in the `c` query parameter, so the load balancer sends every request of it to that server
|
|
14
|
+
- Starts on long polling and upgrades to WebSocket where the network allows, so it works on networks that block WebSockets
|
|
15
|
+
- Reconnects itself, asking where again each time. A room's server that stops answering is tried again 1s, 3s, 5s, 10s and 15s after the connection dropped (`roomRetryMs`, ±10%), each try allowed 4s (`placementTimeoutMs`). Another server is asked alongside the last try, and if the room's server still fails, the TV opens a new room on that server: about 15s after the drop if the room's server's requests fail fast, about 21s if they hang. If no server answers, it's this TV that is offline, and it keeps waiting for the room
|
|
16
|
+
- Retries on another server when one is draining for a deploy or refuses a placement, sending the servers it failed to reach so placement avoids them
|
|
15
17
|
- Holds host calls while a reconnect re-attaches, so nothing reaches the server from a socket it doesn't know the room of
|
|
16
18
|
- Measures the clock offset to the server NTP-style (fastest of 5 pings, every 60s), for starting rounds at an agreed moment
|
|
17
19
|
- Follows its room between servers: when a draining server asks (`room:move`), the client takes the room to a server still taking parties and opens it there under a new code. The phones follow on their own, and host calls made meanwhile wait and are sent to the new server. It also follows `movedTo` when it asks for a room by an old code
|
|
@@ -19,6 +21,16 @@ Host TV client and wire protocol for the multiplayer party games (Name the Artis
|
|
|
19
21
|
- `restart()` on a server past its drain deadline opens a fresh room elsewhere; the phones have to scan the new code
|
|
20
22
|
- Plays `namethesong`, `nametheartist` or `namethesongandartist` (`PartyGameType`). A round's options can carry a `detail` under their `label`: the artist, in Name the Song and Artist
|
|
21
23
|
|
|
24
|
+
## Source
|
|
25
|
+
|
|
26
|
+
| File | What it does |
|
|
27
|
+
|------|--------------|
|
|
28
|
+
| `src/client.ts` | `PartyGameClient`: the session, the game's calls and the room's messages |
|
|
29
|
+
| `src/connection.ts` | `PartyConnection`: placing each socket, reconnecting, and holding host calls until the room is attached |
|
|
30
|
+
| `src/protocol/` | The wire protocol, shared with the server and the phone page: codes, events, messages, placement, limits, scoring |
|
|
31
|
+
| `src/socket.ts` | The little of a socket.io client socket the client uses |
|
|
32
|
+
| `test/` | Tests, mirroring `src/` |
|
|
33
|
+
|
|
22
34
|
## Reference
|
|
23
35
|
|
|
24
36
|
| Type | Function | Arguments | Returns | Description |
|
|
@@ -87,9 +99,12 @@ const results = await client.endRound();
|
|
|
87
99
|
|--------|------|----------|-------------|
|
|
88
100
|
| url | string | Yes | The party servers' global, latency-routed URL (`party-ws.<stage>.cat.roxi.tv`), not the phone page's: where a new room opens |
|
|
89
101
|
| regionUrls | Record\<string, string\> | No | Each region's own URL. A room is reached at its code's region (`PARTY_REGIONS`), so a TV that latency routing sends to another region still finds its room. Without it, everything goes to `url` |
|
|
102
|
+
| fetch | `PartyFetch` | No | How placement is asked. The global `fetch` by default |
|
|
90
103
|
| io | PartySocketFactory | Yes | socket.io-client's `io`, either major version |
|
|
91
104
|
| hostId | string | No | Identifies this TV across its connections; one per process by default |
|
|
92
105
|
| roomMemory | RoomMemory | No | Where the last room code is kept; in memory by default |
|
|
93
106
|
| logger | PartyLogger | No | `debug` and `warn`; `console` by default |
|
|
94
|
-
| ackTimeoutMs | number | No | How long to wait for any answer from the server (8000) |
|
|
107
|
+
| ackTimeoutMs | number | No | How long to wait for any answer from the server but placement (8000) |
|
|
108
|
+
| placementTimeoutMs | number | No | How long a placement request has (4000) |
|
|
109
|
+
| roomRetryMs | number[] | No | When a lost room's server is tried again, in ms since the loss (`[1000, 3000, 5000, 10000, 15000]`); then the room is given up on if another server answers |
|
|
95
110
|
| clockSyncIntervalMs | number | No | How often the clock offset is measured again (60000) |
|
package/dist/client.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type PartyLogger } from './connection';
|
|
2
|
+
import { type HostRestoreRequest, type PartyFetch, type PartyGameType, type PartyHostSession, type PartyPlayer, type PartyRoundConfig, type PartyRoundGo, type PartyRoundResults } from './protocol';
|
|
2
3
|
import type { PartySocketFactory } from './socket';
|
|
4
|
+
export type { PartyLogger } from './connection';
|
|
3
5
|
/**
|
|
4
6
|
* Where the last room this app hosted is remembered, past one client being
|
|
5
7
|
* closed and the next one made.
|
|
@@ -15,10 +17,6 @@ export interface RoomMemory {
|
|
|
15
17
|
get(): string | null;
|
|
16
18
|
set(code: string): void;
|
|
17
19
|
}
|
|
18
|
-
export interface PartyLogger {
|
|
19
|
-
debug(...args: unknown[]): void;
|
|
20
|
-
warn(...args: unknown[]): void;
|
|
21
|
-
}
|
|
22
20
|
export interface PartyGameClientOptions {
|
|
23
21
|
/**
|
|
24
22
|
* The party servers' global name, e.g. `https://party-ws.prod.cat.roxi.tv`:
|
|
@@ -35,6 +33,11 @@ export interface PartyGameClientOptions {
|
|
|
35
33
|
regionUrls?: Record<string, string>;
|
|
36
34
|
/** socket.io-client's `io`: see `PartySocketFactory`. */
|
|
37
35
|
io: PartySocketFactory;
|
|
36
|
+
/**
|
|
37
|
+
* How placement is asked (see PLACEMENT_PATH): the global `fetch` by
|
|
38
|
+
* default, which React Native and the browsers have.
|
|
39
|
+
*/
|
|
40
|
+
fetch?: PartyFetch;
|
|
38
41
|
/**
|
|
39
42
|
* Which TV this is. The server will not hand a room to another TV while its
|
|
40
43
|
* host is connected, and a connection closed on the way into the next lobby
|
|
@@ -45,18 +48,26 @@ export interface PartyGameClientOptions {
|
|
|
45
48
|
/** In memory, for as long as this module is loaded, by default. */
|
|
46
49
|
roomMemory?: RoomMemory;
|
|
47
50
|
logger?: PartyLogger;
|
|
48
|
-
/** How long to wait on the server's answer to anything. */
|
|
51
|
+
/** How long to wait on the server's answer to anything but placement. */
|
|
49
52
|
ackTimeoutMs?: number;
|
|
53
|
+
/**
|
|
54
|
+
* How long a placement request has (see PLACEMENT_PATH): 4s by default. A
|
|
55
|
+
* tiny GET, answered in a few hundred ms; this much allows for a cold HTTPS
|
|
56
|
+
* connection on a poor link. Short, so a room's server that has gone - whose
|
|
57
|
+
* requests hang rather than fail - is found out in time to keep to
|
|
58
|
+
* `roomRetryMs`.
|
|
59
|
+
*/
|
|
60
|
+
placementTimeoutMs?: number;
|
|
50
61
|
/** How often the clock offset to the server is measured again. */
|
|
51
62
|
clockSyncIntervalMs?: number;
|
|
52
63
|
/**
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
64
|
+
* When a room's server is tried again once the connection to it is lost:
|
|
65
|
+
* ms since the loss, 1s, 3s, 5s, 10s and 15s by default. Once every try has
|
|
66
|
+
* failed the client gives up on the room and opens a new one elsewhere - if
|
|
67
|
+
* another server answers, so a TV that is offline itself keeps its room.
|
|
68
|
+
* See PartyConnection.placeFor.
|
|
56
69
|
*/
|
|
57
|
-
|
|
58
|
-
/** How long a region given up on is kept away from. */
|
|
59
|
-
regionDownMs?: number;
|
|
70
|
+
roomRetryMs?: readonly number[];
|
|
60
71
|
}
|
|
61
72
|
type PlayersListener = (players: PartyPlayer[]) => void;
|
|
62
73
|
type AllAnsweredListener = (round: number) => void;
|
|
@@ -71,41 +82,18 @@ type SessionListener = (session: PartyHostSession) => void;
|
|
|
71
82
|
* so navigating from the lobby into the first round keeps the same room and
|
|
72
83
|
* the same players.
|
|
73
84
|
*
|
|
74
|
-
* Rooms live in the memory of one server of several
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
* any server, so once that server has opened one the client connects again
|
|
78
|
-
* with its code - in the lobby, where a moment's reconnect costs nothing,
|
|
79
|
-
* rather than leaving the game on a route the load balancer can take away.
|
|
85
|
+
* Rooms live in the memory of one server of several. Reaching the room's -
|
|
86
|
+
* placing each socket, and placing it again when it drops - is the
|
|
87
|
+
* connection's job: see PartyConnection.
|
|
80
88
|
*/
|
|
81
89
|
export declare class PartyGameClient {
|
|
82
|
-
private readonly
|
|
83
|
-
/** Built in at first, then as the servers say: see PartyRouting. */
|
|
84
|
-
private regionUrls;
|
|
85
|
-
/** Regions given up on, until when: their rooms are looked for through the global name. */
|
|
86
|
-
private downRegions;
|
|
87
|
-
private readonly io;
|
|
90
|
+
private readonly connection;
|
|
88
91
|
private readonly hostId;
|
|
89
92
|
private readonly roomMemory;
|
|
90
93
|
private readonly logger;
|
|
91
|
-
private readonly ackTimeoutMs;
|
|
92
94
|
private readonly clockSyncIntervalMs;
|
|
93
|
-
|
|
94
|
-
private
|
|
95
|
-
/** Runs while the current socket, routed to a room's region, is not connected. */
|
|
96
|
-
private regionTimer;
|
|
97
|
-
/** A connection to the global name, seeing whether it is the region that is out of reach. */
|
|
98
|
-
private regionProbe;
|
|
99
|
-
private socket;
|
|
100
|
-
/** The room code the current socket was routed by, if any. */
|
|
101
|
-
private routedCode;
|
|
102
|
-
/**
|
|
103
|
-
* Whether the current connection is attached to the session's room. Host
|
|
104
|
-
* calls wait for it: sent while a reconnect is still re-attaching, they
|
|
105
|
-
* would reach the server from a socket it does not know the room of.
|
|
106
|
-
*/
|
|
107
|
-
private attached;
|
|
108
|
-
private attachedWaiters;
|
|
95
|
+
/** Roster changes for a room this TV is about to be handed: see adopt. */
|
|
96
|
+
private earlyFlags;
|
|
109
97
|
private session;
|
|
110
98
|
/** Where the session's room is now, when a server has said it moved. */
|
|
111
99
|
private redirectCode;
|
|
@@ -139,30 +127,9 @@ export declare class PartyGameClient {
|
|
|
139
127
|
url: string;
|
|
140
128
|
bytes: number;
|
|
141
129
|
} | null;
|
|
142
|
-
/**
|
|
143
|
-
private
|
|
144
|
-
private
|
|
145
|
-
private setAttached;
|
|
146
|
-
private whenAttached;
|
|
147
|
-
/**
|
|
148
|
-
* Where `code`'s room is: its region's servers, or for no room - or one in
|
|
149
|
-
* a region given up on - the nearest.
|
|
150
|
-
*/
|
|
151
|
-
private urlFor;
|
|
152
|
-
/** A socket routed by `code`, to `url` (by default, where `code`'s room is). */
|
|
153
|
-
private connectTo;
|
|
154
|
-
/**
|
|
155
|
-
* Gives a room's region `regionFallbackMs` to answer `socket`, routed to it
|
|
156
|
-
* by `code` (null stops watching). A region that does not is checked
|
|
157
|
-
* against the global name: if that answers, the region is down - its rooms
|
|
158
|
-
* with it, as a room lives in one server's memory - so the client goes
|
|
159
|
-
* through the global name instead, where the room's code gets a new room,
|
|
160
|
-
* in a region that is up. If it does not either, it is this TV that is
|
|
161
|
-
* offline, and the room is waited for: it may well still be there.
|
|
162
|
-
*/
|
|
163
|
-
private watchRegion;
|
|
164
|
-
private closeRegionProbe;
|
|
165
|
-
private openSocket;
|
|
130
|
+
/** Listens for the room's messages on a socket the connection has opened. */
|
|
131
|
+
private listen;
|
|
132
|
+
private setPlayers;
|
|
166
133
|
/**
|
|
167
134
|
* Back on the room we were already hosting, so a dropped connection
|
|
168
135
|
* mid-party does not lose the players or their scores. If the room is gone
|
|
@@ -171,7 +138,6 @@ export declare class PartyGameClient {
|
|
|
171
138
|
private reattach;
|
|
172
139
|
/** Takes on a session the server has handed back, rerouting by its code if need be. */
|
|
173
140
|
private adopt;
|
|
174
|
-
private send;
|
|
175
141
|
private emit;
|
|
176
142
|
private moveRoom;
|
|
177
143
|
/**
|
|
@@ -265,5 +231,4 @@ export declare class PartyGameClient {
|
|
|
265
231
|
/** Leaves the room entirely - the next `host()` opens a fresh one. */
|
|
266
232
|
close(): void;
|
|
267
233
|
}
|
|
268
|
-
export {};
|
|
269
234
|
//# sourceMappingURL=client.d.ts.map
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAeL,KAAK,kBAAkB,EAGvB,KAAK,aAAa,EAClB,KAAK,gBAAgB,EACrB,KAAK,WAAW,
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|