@tailuge/messaging 1.4.0 → 1.7.0

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/MESSAGING_SPEC.md CHANGED
@@ -140,7 +140,7 @@ interface Meta {
140
140
  ts: string; // ISO timestamp of the request (Source of Truth for time)
141
141
  ua: string; // User-Agent header
142
142
  ip: string; // Client remote address
143
- host: string; // Host header value
143
+ origin: string; // Origin header value
144
144
  method: string; // HTTP method (always POST for publish)
145
145
  country: string; // Country code from IP (e.g., "US", "GB", "XX")
146
146
  city: string; // City from IP geolocation
@@ -172,6 +172,56 @@ interface PresenceMessage {
172
172
  }
173
173
  ```
174
174
 
175
+ #### External Game Integration
176
+
177
+ When users are redirected from the lobby to an external game page (e.g., billiards), the game page can maintain the user's presence as "in a table" by passing `tableId` when joining the lobby:
178
+
179
+ ```typescript
180
+ // In the external game page
181
+ const client = new MessagingClient({ baseUrl: nchanUrl });
182
+
183
+ // Join lobby with tableId already set - lobby users see this player as "in game"
184
+ const lobby = await client.joinLobby({
185
+ messageType: "presence",
186
+ type: "join",
187
+ userId: "player1",
188
+ userName: "Player One",
189
+ tableId: "table-123", // Marks user as at table-123
190
+ });
191
+ ```
192
+
193
+ This is useful when:
194
+ - The game was launched from a URL with tableId (e.g., after challenge acceptance)
195
+ - The new page creates a fresh MessagingClient but wants to preserve presence state
196
+ - Other lobby users should see this player as "currently in a game"
197
+
198
+ To clear the table status (e.g., when the game ends):
199
+ ```typescript
200
+ await lobby.updatePresence({ tableId: undefined });
201
+ ```
202
+
203
+ **Page unload:** When the lobby page unloads, a `leave` message is sent automatically. The external game page is expected to call `joinLobby()` with `tableId` to re-establish presence as "in game". This ensures no ghost users if the redirect fails.
204
+
205
+ #### Minimal Presence for Games
206
+
207
+ Games that only need online user count (no table joining):
208
+
209
+ ```typescript
210
+ // Join without tableId - user appears as "available" in lobby
211
+ await client.joinLobby({
212
+ messageType: "presence",
213
+ type: "join",
214
+ userId: "player1",
215
+ userName: "Player One",
216
+ });
217
+
218
+ // Add tableId when starting a multiplayer game
219
+ await lobby.updatePresence({ tableId: "table-123" });
220
+
221
+ // Remove tableId when game ends
222
+ await lobby.updatePresence({ tableId: undefined });
223
+ ```
224
+
175
225
  ### `ChallengeMessage`
176
226
 
177
227
  Represents a peer-to-peer challenge request.
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
- export * from "./messagingclient";
2
- export * from "./lobby";
3
- export * from "./table";
4
- export * from "./types";
5
- export * from "./nchanclient";
1
+ export * from "./messagingclient.js";
2
+ export * from "./lobby.js";
3
+ export * from "./table.js";
4
+ export * from "./types.js";
5
+ export * from "./nchanclient.js";
6
6
  //# sourceMappingURL=index.js.map
package/dist/lobby.js CHANGED
@@ -1,6 +1,6 @@
1
- import { parseMessage } from "./types";
2
- import { Table } from "./table";
3
- import { getUID } from "./utils/uid";
1
+ import { parseMessage } from "./types.js";
2
+ import { Table } from "./table.js";
3
+ import { getUID } from "./utils/uid.js";
4
4
  /**
5
5
  * Manages the global lobby state, including real-time presence tracking and challenge flows.
6
6
  */
@@ -1,6 +1,6 @@
1
- import { NchanClient } from "./nchanclient";
2
- import { Lobby } from "./lobby";
3
- import { Table } from "./table";
1
+ import { NchanClient } from "./nchanclient.js";
2
+ import { Lobby } from "./lobby.js";
3
+ import { Table } from "./table.js";
4
4
  /**
5
5
  * The main messaging client library entry point.
6
6
  * Encapsulates transport logic and provides access to lobby and table functionality.
package/dist/table.js CHANGED
@@ -1,4 +1,4 @@
1
- import { parseMessage } from "./types";
1
+ import { parseMessage } from "./types.js";
2
2
  /**
3
3
  * Represents a specific communication channel for a 2-player/spectator scenario at a table.
4
4
  * Uses `any` as default for internal storage flexibility; consumers should use `unknown` or specific types.
package/dist/types.d.ts CHANGED
@@ -6,7 +6,7 @@ export interface Meta {
6
6
  ts: string;
7
7
  ua: string;
8
8
  ip: string;
9
- host: string;
9
+ origin: string;
10
10
  method: string;
11
11
  country: string;
12
12
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tailuge/messaging",
3
- "version": "1.4.0",
3
+ "version": "1.7.0",
4
4
  "type": "module",
5
5
  "description": "A stateful messaging library for Nchan-powered real-time applications.",
6
6
  "main": "./dist/index.js",
@@ -23,7 +23,7 @@
23
23
  "test:debug": "npm run playwright",
24
24
  "lint": "tsc --noEmit && npx oxlint src test",
25
25
  "prettify": "npx oxfmt src test",
26
- "build": "tsc --declaration",
26
+ "build": "tsc --declaration && node scripts/add-js-extensions.js",
27
27
  "release": "npm version minor --no-git-tag-version && npm run build",
28
28
  "build:all": "npm run build && npm run build:example && npm run docker:start",
29
29
  "build:example": "mkdir -p docker/html/example && npx esbuild example/src/client.ts --bundle --outfile=docker/html/example/client.js && cp example/*.html docker/html/example/",