@tailuge/messaging 1.11.0 → 1.13.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 +30 -0
- package/SKILL.md +10 -0
- package/dist/ChallengeDeduplicator.js +3 -1
- package/dist/ChallengeDeduplicator.js.map +1 -1
- package/dist/lobby.d.ts +18 -1
- package/dist/lobby.js +48 -1
- package/dist/lobby.js.map +1 -1
- package/dist/messagingclient.d.ts +13 -1
- package/dist/messagingclient.js +90 -28
- package/dist/messagingclient.js.map +1 -1
- package/dist/nchanclient.d.ts +5 -1
- package/dist/nchanclient.js +28 -15
- package/dist/nchanclient.js.map +1 -1
- package/dist/types.d.ts +12 -1
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -1
- package/package.json +3 -3
package/MESSAGING_SPEC.md
CHANGED
|
@@ -92,6 +92,16 @@ interface Lobby {
|
|
|
92
92
|
*/
|
|
93
93
|
onChallenge(callback: (challenge: ChallengeMessage) => void): void;
|
|
94
94
|
|
|
95
|
+
/**
|
|
96
|
+
* Send a chat message to another user.
|
|
97
|
+
*/
|
|
98
|
+
sendChat(recipientId: string, text: string): Promise<void>;
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Subscribe to incoming chat messages directed at the current user.
|
|
102
|
+
*/
|
|
103
|
+
onChat(callback: (message: ChatMessage) => void): void;
|
|
104
|
+
|
|
95
105
|
/**
|
|
96
106
|
* Leave the lobby.
|
|
97
107
|
*/
|
|
@@ -251,6 +261,20 @@ interface ChallengeMessage {
|
|
|
251
261
|
}
|
|
252
262
|
```
|
|
253
263
|
|
|
264
|
+
### `ChatMessage`
|
|
265
|
+
|
|
266
|
+
Represents a peer-to-peer chat message.
|
|
267
|
+
|
|
268
|
+
```typescript
|
|
269
|
+
interface ChatMessage {
|
|
270
|
+
messageType: "chat";
|
|
271
|
+
senderId: string;
|
|
272
|
+
recipientId: string;
|
|
273
|
+
text: string;
|
|
274
|
+
meta?: Meta; // Server-enriched metadata (received messages only)
|
|
275
|
+
}
|
|
276
|
+
```
|
|
277
|
+
|
|
254
278
|
### `TableInfo` (UNDER REVIEW)
|
|
255
279
|
|
|
256
280
|
Lobby-level information about an active game table.
|
|
@@ -405,6 +429,12 @@ const lobby = await client.joinLobby({
|
|
|
405
429
|
userName: "Alice",
|
|
406
430
|
});
|
|
407
431
|
|
|
432
|
+
lobby.onChat((msg) => {
|
|
433
|
+
console.log(`Chat from ${msg.senderId}: ${msg.text}`);
|
|
434
|
+
});
|
|
435
|
+
|
|
436
|
+
await lobby.sendChat("user-456", "Hi Bob!");
|
|
437
|
+
|
|
408
438
|
lobby.onUsersChange((users) => {
|
|
409
439
|
console.log("Online users:", users.length);
|
|
410
440
|
});
|
package/SKILL.md
CHANGED
|
@@ -56,6 +56,16 @@ lobby.onChallenge((challenge) => {
|
|
|
56
56
|
lobby.acceptChallenge(challenge.challengerId, challenge.ruleType, challenge.tableId);
|
|
57
57
|
}
|
|
58
58
|
});
|
|
59
|
+
|
|
60
|
+
## Chat
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
await lobby.sendChat(targetUserId, "Hello!");
|
|
64
|
+
|
|
65
|
+
lobby.onChat((msg) => {
|
|
66
|
+
console.log(`Message from ${msg.senderId}: ${msg.text}`);
|
|
67
|
+
});
|
|
68
|
+
```
|
|
59
69
|
```
|
|
60
70
|
|
|
61
71
|
## Table Messaging
|
|
@@ -15,7 +15,9 @@ export class ChallengeDeduplicator {
|
|
|
15
15
|
this.onEmit(msg);
|
|
16
16
|
this.pendingOffers.delete(interactionKey);
|
|
17
17
|
}, 250);
|
|
18
|
-
timeoutId
|
|
18
|
+
if (timeoutId && typeof timeoutId === 'object' && 'unref' in timeoutId) {
|
|
19
|
+
timeoutId.unref();
|
|
20
|
+
}
|
|
19
21
|
this.pendingOffers.set(interactionKey, timeoutId);
|
|
20
22
|
}
|
|
21
23
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChallengeDeduplicator.js","sourceRoot":"","sources":["../src/ChallengeDeduplicator.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,qBAAqB;IAIhC,YAAY,MAA6C;QAFjD,kBAAa,GAAG,IAAI,GAAG,
|
|
1
|
+
{"version":3,"file":"ChallengeDeduplicator.js","sourceRoot":"","sources":["../src/ChallengeDeduplicator.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,qBAAqB;IAIhC,YAAY,MAA6C;QAFjD,kBAAa,GAAG,IAAI,GAAG,EAAyC,CAAC;QAGvE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAEM,cAAc,CAAC,GAAqB,EAAE,aAAqB;QAChE,yFAAyF;QACzF,MAAM,cAAc,GAAG,CAAC,GAAG,CAAC,YAAY,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAE5E,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YACzB,qCAAqC;YACrC,IAAI,GAAG,CAAC,WAAW,KAAK,aAAa,EAAE,CAAC;gBACtC,mEAAmE;gBACnE,IAAI,CAAC,gBAAgB,CAAC,cAAc,CAAC,CAAC;gBAEtC,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE;oBAChC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;oBACjB,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;gBAC5C,CAAC,EAAE,GAAG,CAAC,CAAC;gBAER,IAAI,SAAS,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,OAAO,IAAI,SAAS,EAAE,CAAC;oBACtE,SAAiB,CAAC,KAAK,EAAE,CAAC;gBAC7B,CAAC;gBAED,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC;YACpD,CAAC;QACH,CAAC;aAAM,CAAC;YACN,yCAAyC;YACzC,6EAA6E;YAC7E,IAAI,CAAC,gBAAgB,CAAC,cAAc,CAAC,CAAC;YAEtC,sEAAsE;YACtE,IAAI,GAAG,CAAC,WAAW,KAAK,aAAa,EAAE,CAAC;gBACtC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACnB,CAAC;QACH,CAAC;IACH,CAAC;IAEO,gBAAgB,CAAC,GAAW;QAClC,MAAM,SAAS,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC9C,IAAI,SAAS,EAAE,CAAC;YACd,YAAY,CAAC,SAAS,CAAC,CAAC;YACxB,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;IAEM,KAAK;QACV,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,EAAE,CAAC;YACpD,YAAY,CAAC,SAAS,CAAC,CAAC;QAC1B,CAAC;QACD,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;IAC7B,CAAC;CACF"}
|
package/dist/lobby.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { NchanClient } from "./nchanclient";
|
|
2
|
-
import { PresenceMessage, ChallengeMessage, RematchInfo } from "./types";
|
|
2
|
+
import { PresenceMessage, ChallengeMessage, RematchInfo, ChatMessage } from "./types";
|
|
3
3
|
import { Table } from "./table";
|
|
4
4
|
export interface LobbyOptions {
|
|
5
5
|
heartbeatInterval?: number;
|
|
6
6
|
pruneInterval?: number;
|
|
7
7
|
staleTtl?: number;
|
|
8
|
+
onReconnect?: () => void;
|
|
8
9
|
}
|
|
9
10
|
/**
|
|
10
11
|
* Manages the global lobby state, including real-time presence tracking and challenge flows.
|
|
@@ -12,9 +13,11 @@ export interface LobbyOptions {
|
|
|
12
13
|
export declare class Lobby {
|
|
13
14
|
private nchan;
|
|
14
15
|
currentUser: PresenceMessage;
|
|
16
|
+
private options;
|
|
15
17
|
private users;
|
|
16
18
|
private listeners;
|
|
17
19
|
private challengeListeners;
|
|
20
|
+
private chatListeners;
|
|
18
21
|
private pendingChallenges;
|
|
19
22
|
private deduplicator;
|
|
20
23
|
private subscription;
|
|
@@ -25,6 +28,14 @@ export declare class Lobby {
|
|
|
25
28
|
private readonly pruneInterval;
|
|
26
29
|
private readonly staleTtl;
|
|
27
30
|
constructor(nchan: NchanClient, currentUser: PresenceMessage, options?: LobbyOptions);
|
|
31
|
+
/**
|
|
32
|
+
* Subscribe to incoming chat messages directed at the current user.
|
|
33
|
+
*/
|
|
34
|
+
onChat(callback: (message: ChatMessage) => void): void;
|
|
35
|
+
/**
|
|
36
|
+
* Send a chat message to another user.
|
|
37
|
+
*/
|
|
38
|
+
sendChat(recipientId: string, text: string): Promise<void>;
|
|
28
39
|
/**
|
|
29
40
|
* Initializes the lobby by subscribing to presence events and broadcasting "join".
|
|
30
41
|
*/
|
|
@@ -53,6 +64,11 @@ export declare class Lobby {
|
|
|
53
64
|
* Allows updating the current user's status (e.g. name or playing state).
|
|
54
65
|
*/
|
|
55
66
|
updatePresence(update: Partial<PresenceMessage>): Promise<void>;
|
|
67
|
+
/**
|
|
68
|
+
* Proactively re-publishes the current presence state to the lobby.
|
|
69
|
+
* Useful for session restoration or ensuring state synchronization.
|
|
70
|
+
*/
|
|
71
|
+
syncPresence(): Promise<void>;
|
|
56
72
|
/**
|
|
57
73
|
* Challenge another user to a game.
|
|
58
74
|
* Returns the ID of the table created for the challenge.
|
|
@@ -90,6 +106,7 @@ export declare class Lobby {
|
|
|
90
106
|
*/
|
|
91
107
|
private handlePresenceUpdate;
|
|
92
108
|
private handleChallenge;
|
|
109
|
+
private handleChat;
|
|
93
110
|
private notifyListeners;
|
|
94
111
|
private getUsersList;
|
|
95
112
|
}
|
package/dist/lobby.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { parseMessage } from "./types.js";
|
|
1
|
+
import { parseMessage, } from "./types.js";
|
|
2
2
|
import { Table } from "./table.js";
|
|
3
3
|
import { getUID } from "./utils/uid.js";
|
|
4
4
|
import { ChallengeDeduplicator } from "./ChallengeDeduplicator.js";
|
|
@@ -9,9 +9,11 @@ export class Lobby {
|
|
|
9
9
|
constructor(nchan, currentUser, options = {}) {
|
|
10
10
|
this.nchan = nchan;
|
|
11
11
|
this.currentUser = currentUser;
|
|
12
|
+
this.options = options;
|
|
12
13
|
this.users = new Map();
|
|
13
14
|
this.listeners = [];
|
|
14
15
|
this.challengeListeners = [];
|
|
16
|
+
this.chatListeners = [];
|
|
15
17
|
this.pendingChallenges = [];
|
|
16
18
|
this.subscription = null;
|
|
17
19
|
this.isJoined = false;
|
|
@@ -23,6 +25,22 @@ export class Lobby {
|
|
|
23
25
|
this.challengeListeners.forEach((cb) => cb(msg));
|
|
24
26
|
});
|
|
25
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* Subscribe to incoming chat messages directed at the current user.
|
|
30
|
+
*/
|
|
31
|
+
onChat(callback) {
|
|
32
|
+
this.chatListeners.push(callback);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Send a chat message to another user.
|
|
36
|
+
*/
|
|
37
|
+
async sendChat(recipientId, text) {
|
|
38
|
+
await this.nchan.publishChat({
|
|
39
|
+
senderId: this.currentUser.userId,
|
|
40
|
+
recipientId,
|
|
41
|
+
text,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
26
44
|
/**
|
|
27
45
|
* Initializes the lobby by subscribing to presence events and broadcasting "join".
|
|
28
46
|
*/
|
|
@@ -32,6 +50,20 @@ export class Lobby {
|
|
|
32
50
|
this.subscription = this.nchan.subscribePresence((data) => {
|
|
33
51
|
this.handleIncomingMessage(data);
|
|
34
52
|
});
|
|
53
|
+
this.subscription.onReconnect = () => {
|
|
54
|
+
// Trigger any external reconnect handlers first (e.g., MessagingClient.resumeSession)
|
|
55
|
+
// This allows centralized orchestration to handle state and presence updates.
|
|
56
|
+
this.resumeHeartbeat();
|
|
57
|
+
if (this.options.onReconnect) {
|
|
58
|
+
this.options.onReconnect();
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
// Fallback: Re-broadcast presence state if no external orchestrator is handling it
|
|
62
|
+
this.nchan.publishPresence(this.currentUser).catch((_e) => {
|
|
63
|
+
console.error("Failed to re-broadcast presence on reconnect:", _e);
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
};
|
|
35
67
|
await this.subscription.ready;
|
|
36
68
|
// Broadcast our own presence
|
|
37
69
|
await this.nchan.publishPresence(this.currentUser);
|
|
@@ -117,6 +149,13 @@ export class Lobby {
|
|
|
117
149
|
*/
|
|
118
150
|
async updatePresence(update) {
|
|
119
151
|
this.currentUser = { ...this.currentUser, ...update };
|
|
152
|
+
await this.syncPresence();
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Proactively re-publishes the current presence state to the lobby.
|
|
156
|
+
* Useful for session restoration or ensuring state synchronization.
|
|
157
|
+
*/
|
|
158
|
+
async syncPresence() {
|
|
120
159
|
await this.nchan.publishPresence(this.currentUser);
|
|
121
160
|
}
|
|
122
161
|
/**
|
|
@@ -219,6 +258,9 @@ export class Lobby {
|
|
|
219
258
|
else if (rawMsg.messageType === "challenge") {
|
|
220
259
|
this.handleChallenge(rawMsg);
|
|
221
260
|
}
|
|
261
|
+
else if (rawMsg.messageType === "chat") {
|
|
262
|
+
this.handleChat(rawMsg);
|
|
263
|
+
}
|
|
222
264
|
}
|
|
223
265
|
/**
|
|
224
266
|
* Handles incoming presence updates.
|
|
@@ -238,6 +280,11 @@ export class Lobby {
|
|
|
238
280
|
// Deduplicator tracks state from ALL challenge interactions (offer, accept, decline, cancel)
|
|
239
281
|
this.deduplicator.processMessage(msg, this.currentUser.userId);
|
|
240
282
|
}
|
|
283
|
+
handleChat(msg) {
|
|
284
|
+
if (msg.recipientId === this.currentUser.userId) {
|
|
285
|
+
this.chatListeners.forEach((cb) => cb(msg));
|
|
286
|
+
}
|
|
287
|
+
}
|
|
241
288
|
notifyListeners() {
|
|
242
289
|
const list = this.getUsersList();
|
|
243
290
|
this.listeners.forEach((cb) => cb(list));
|
package/dist/lobby.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lobby.js","sourceRoot":"","sources":["../src/lobby.ts"],"names":[],"mappings":"AACA,OAAO,
|
|
1
|
+
{"version":3,"file":"lobby.js","sourceRoot":"","sources":["../src/lobby.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,9 +9,12 @@ export declare class MessagingClient {
|
|
|
9
9
|
private nchan;
|
|
10
10
|
private activeLobbies;
|
|
11
11
|
private activeTables;
|
|
12
|
-
private
|
|
12
|
+
private lobbyConfigs;
|
|
13
13
|
private isStopping;
|
|
14
14
|
private isStarted;
|
|
15
|
+
private listenersAttached;
|
|
16
|
+
private resumePromise;
|
|
17
|
+
private joiningLobbies;
|
|
15
18
|
constructor(options: {
|
|
16
19
|
baseUrl: string;
|
|
17
20
|
});
|
|
@@ -32,6 +35,10 @@ export declare class MessagingClient {
|
|
|
32
35
|
* to implement message ordering or deduplication based on meta.ts timestamps.
|
|
33
36
|
*/
|
|
34
37
|
joinLobby(user: PresenceMessage, options?: LobbyOptions): Promise<Lobby>;
|
|
38
|
+
/**
|
|
39
|
+
* Gracefully leaves a lobby.
|
|
40
|
+
*/
|
|
41
|
+
leaveLobby(userId: string): Promise<void>;
|
|
35
42
|
/**
|
|
36
43
|
* Joins a specific table for communication.
|
|
37
44
|
*/
|
|
@@ -39,4 +46,9 @@ export declare class MessagingClient {
|
|
|
39
46
|
private handlePageHide;
|
|
40
47
|
private handlePageShow;
|
|
41
48
|
private handleVisibilityChange;
|
|
49
|
+
/**
|
|
50
|
+
* Central orchestrator for session restoration.
|
|
51
|
+
* Ensures connection, lobby joins, and presence sync after a lifecycle event or reconnect.
|
|
52
|
+
*/
|
|
53
|
+
resumeSession(): Promise<void>;
|
|
42
54
|
}
|
package/dist/messagingclient.js
CHANGED
|
@@ -9,8 +9,12 @@ export class MessagingClient {
|
|
|
9
9
|
constructor(options) {
|
|
10
10
|
this.activeLobbies = [];
|
|
11
11
|
this.activeTables = [];
|
|
12
|
+
this.lobbyConfigs = new Map();
|
|
12
13
|
this.isStopping = false;
|
|
13
14
|
this.isStarted = false;
|
|
15
|
+
this.listenersAttached = false;
|
|
16
|
+
this.resumePromise = null;
|
|
17
|
+
this.joiningLobbies = new Map();
|
|
14
18
|
this.handlePageHide = () => {
|
|
15
19
|
// Stop all connections on page hide (prevent ghosting)
|
|
16
20
|
// Non-blocking call because pagehide might terminate the process
|
|
@@ -18,21 +22,16 @@ export class MessagingClient {
|
|
|
18
22
|
};
|
|
19
23
|
this.handlePageShow = async (event) => {
|
|
20
24
|
// If returning via bfcache, restore connections
|
|
21
|
-
if (event.persisted
|
|
22
|
-
|
|
23
|
-
await this.joinLobby(this.lastLobbyConfig.user, this.lastLobbyConfig.options);
|
|
24
|
-
}
|
|
25
|
-
catch (e) {
|
|
26
|
-
console.error("Failed to restore lobby on pageshow:", e);
|
|
27
|
-
}
|
|
25
|
+
if (event.persisted) {
|
|
26
|
+
await this.resumeSession();
|
|
28
27
|
}
|
|
29
28
|
};
|
|
30
|
-
this.handleVisibilityChange = () => {
|
|
31
|
-
if (document.hidden) {
|
|
29
|
+
this.handleVisibilityChange = async () => {
|
|
30
|
+
if (document.visibilityState === "hidden") {
|
|
32
31
|
this.activeLobbies.forEach((l) => l.pauseHeartbeat());
|
|
33
32
|
}
|
|
34
|
-
else {
|
|
35
|
-
this.
|
|
33
|
+
else if (document.visibilityState === "visible") {
|
|
34
|
+
await this.resumeSession();
|
|
36
35
|
}
|
|
37
36
|
};
|
|
38
37
|
this.nchan = new NchanClient(options.baseUrl);
|
|
@@ -42,13 +41,14 @@ export class MessagingClient {
|
|
|
42
41
|
* In browser environments, attaches lifecycle event listeners.
|
|
43
42
|
*/
|
|
44
43
|
start() {
|
|
45
|
-
if (this.
|
|
46
|
-
return;
|
|
47
|
-
if (typeof window !== "undefined") {
|
|
44
|
+
if (typeof window !== "undefined" && !this.listenersAttached) {
|
|
48
45
|
window.addEventListener("pagehide", this.handlePageHide);
|
|
49
46
|
window.addEventListener("pageshow", this.handlePageShow);
|
|
50
47
|
document.addEventListener("visibilitychange", this.handleVisibilityChange);
|
|
48
|
+
this.listenersAttached = true;
|
|
51
49
|
}
|
|
50
|
+
if (this.isStarted)
|
|
51
|
+
return;
|
|
52
52
|
this.isStarted = true;
|
|
53
53
|
}
|
|
54
54
|
/**
|
|
@@ -59,11 +59,6 @@ export class MessagingClient {
|
|
|
59
59
|
return;
|
|
60
60
|
this.isStopping = true;
|
|
61
61
|
try {
|
|
62
|
-
if (typeof window !== "undefined") {
|
|
63
|
-
window.removeEventListener("pagehide", this.handlePageHide);
|
|
64
|
-
window.removeEventListener("pageshow", this.handlePageShow);
|
|
65
|
-
document.removeEventListener("visibilitychange", this.handleVisibilityChange);
|
|
66
|
-
}
|
|
67
62
|
this.isStarted = false;
|
|
68
63
|
const lobbies = [...this.activeLobbies];
|
|
69
64
|
this.activeLobbies = [];
|
|
@@ -84,15 +79,50 @@ export class MessagingClient {
|
|
|
84
79
|
*/
|
|
85
80
|
async joinLobby(user, options) {
|
|
86
81
|
this.start();
|
|
87
|
-
// Prevent duplicate joins
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
82
|
+
// Prevent duplicate concurrent joins for the same user
|
|
83
|
+
if (this.joiningLobbies.has(user.userId)) {
|
|
84
|
+
return this.joiningLobbies.get(user.userId);
|
|
85
|
+
}
|
|
86
|
+
const joinPromise = (async () => {
|
|
87
|
+
try {
|
|
88
|
+
// Prevent duplicate joins if already in a lobby for this user
|
|
89
|
+
const existing = this.activeLobbies.find((l) => l.currentUser.userId === user.userId);
|
|
90
|
+
const lobbyOptions = {
|
|
91
|
+
...options,
|
|
92
|
+
onReconnect: () => {
|
|
93
|
+
// When any lobby reconnects, ensure the whole session is healthy
|
|
94
|
+
this.resumeSession().catch((e) => console.error("Session resume failed after lobby reconnect:", e));
|
|
95
|
+
options?.onReconnect?.();
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
this.lobbyConfigs.set(user.userId, { user, options });
|
|
99
|
+
if (existing) {
|
|
100
|
+
existing.resumeHeartbeat();
|
|
101
|
+
return existing;
|
|
102
|
+
}
|
|
103
|
+
const lobby = new Lobby(this.nchan, user, lobbyOptions);
|
|
104
|
+
await lobby.join();
|
|
105
|
+
this.activeLobbies.push(lobby);
|
|
106
|
+
return lobby;
|
|
107
|
+
}
|
|
108
|
+
finally {
|
|
109
|
+
this.joiningLobbies.delete(user.userId);
|
|
110
|
+
}
|
|
111
|
+
})();
|
|
112
|
+
this.joiningLobbies.set(user.userId, joinPromise);
|
|
113
|
+
return joinPromise;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Gracefully leaves a lobby.
|
|
117
|
+
*/
|
|
118
|
+
async leaveLobby(userId) {
|
|
119
|
+
const index = this.activeLobbies.findIndex((l) => l.currentUser.userId === userId);
|
|
120
|
+
if (index !== -1) {
|
|
121
|
+
const lobby = this.activeLobbies[index];
|
|
122
|
+
await lobby.leave();
|
|
123
|
+
this.activeLobbies.splice(index, 1);
|
|
124
|
+
}
|
|
125
|
+
this.lobbyConfigs.delete(userId);
|
|
96
126
|
}
|
|
97
127
|
/**
|
|
98
128
|
* Joins a specific table for communication.
|
|
@@ -113,5 +143,37 @@ export class MessagingClient {
|
|
|
113
143
|
await lobby.updatePresence({ tableId });
|
|
114
144
|
return table;
|
|
115
145
|
}
|
|
146
|
+
/**
|
|
147
|
+
* Central orchestrator for session restoration.
|
|
148
|
+
* Ensures connection, lobby joins, and presence sync after a lifecycle event or reconnect.
|
|
149
|
+
*/
|
|
150
|
+
async resumeSession() {
|
|
151
|
+
if (this.resumePromise)
|
|
152
|
+
return this.resumePromise;
|
|
153
|
+
this.resumePromise = (async () => {
|
|
154
|
+
try {
|
|
155
|
+
if (!this.isStarted && this.lobbyConfigs.size > 0) {
|
|
156
|
+
this.isStarted = true;
|
|
157
|
+
const configs = Array.from(this.lobbyConfigs.values());
|
|
158
|
+
await Promise.all(configs.map((c) => this.joinLobby(c.user, c.options)));
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
await Promise.all(this.activeLobbies.map(async (l) => {
|
|
162
|
+
l.resumeHeartbeat();
|
|
163
|
+
// Proactively re-publish presence to ensure we're seen as online
|
|
164
|
+
try {
|
|
165
|
+
await l.syncPresence();
|
|
166
|
+
}
|
|
167
|
+
catch (e) {
|
|
168
|
+
console.error("Failed to refresh presence during session resume:", e);
|
|
169
|
+
}
|
|
170
|
+
}));
|
|
171
|
+
}
|
|
172
|
+
finally {
|
|
173
|
+
this.resumePromise = null;
|
|
174
|
+
}
|
|
175
|
+
})();
|
|
176
|
+
return this.resumePromise;
|
|
177
|
+
}
|
|
116
178
|
}
|
|
117
179
|
//# sourceMappingURL=messagingclient.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messagingclient.js","sourceRoot":"","sources":["../src/messagingclient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,KAAK,EAAgB,MAAM,SAAS,CAAC;AAC9C,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAGhC;;;GAGG;AACH,MAAM,OAAO,eAAe;
|
|
1
|
+
{"version":3,"file":"messagingclient.js","sourceRoot":"","sources":["../src/messagingclient.ts"],"names":[],"mappings":"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"}
|
package/dist/nchanclient.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import type { PresenceMessage, ChallengeMessage, TableMessage } from "./types";
|
|
1
|
+
import type { PresenceMessage, ChallengeMessage, TableMessage, ChatMessage } from "./types";
|
|
2
2
|
export type Subscription = {
|
|
3
3
|
stop: () => void;
|
|
4
4
|
ready: Promise<void>;
|
|
5
|
+
onReconnect?: () => void;
|
|
5
6
|
};
|
|
6
7
|
export declare class NchanClient {
|
|
7
8
|
private server;
|
|
@@ -15,6 +16,9 @@ export declare class NchanClient {
|
|
|
15
16
|
publishChallenge(message: Omit<ChallengeMessage, "messageType">, options?: {
|
|
16
17
|
keepalive?: boolean;
|
|
17
18
|
}): Promise<Response>;
|
|
19
|
+
publishChat(message: Omit<ChatMessage, "messageType" | "meta">, options?: {
|
|
20
|
+
keepalive?: boolean;
|
|
21
|
+
}): Promise<Response>;
|
|
18
22
|
publishTable<T>(tableId: string, message: Omit<TableMessage<T>, "senderId">, senderId: string, options?: {
|
|
19
23
|
keepalive?: boolean;
|
|
20
24
|
}): Promise<Response>;
|
package/dist/nchanclient.js
CHANGED
|
@@ -54,6 +54,12 @@ export class NchanClient {
|
|
|
54
54
|
messageType: "challenge",
|
|
55
55
|
}, options);
|
|
56
56
|
}
|
|
57
|
+
async publishChat(message, options) {
|
|
58
|
+
return this.publish(PATHS.PRESENCE_PUBLISH, {
|
|
59
|
+
...message,
|
|
60
|
+
messageType: "chat",
|
|
61
|
+
}, options);
|
|
62
|
+
}
|
|
57
63
|
async publishTable(tableId, message, senderId, options) {
|
|
58
64
|
return this.publish(PATHS.TABLE_PUBLISH(tableId), {
|
|
59
65
|
...message,
|
|
@@ -74,8 +80,23 @@ export class NchanClient {
|
|
|
74
80
|
let reconnectAttempts = 0;
|
|
75
81
|
const maxReconnectDelay = 30000;
|
|
76
82
|
let reconnectTimer = null;
|
|
83
|
+
let firstConnection = true;
|
|
84
|
+
const subscription = {
|
|
85
|
+
stop: () => {
|
|
86
|
+
stopped = true;
|
|
87
|
+
if (reconnectTimer) {
|
|
88
|
+
clearTimeout(reconnectTimer);
|
|
89
|
+
reconnectTimer = null;
|
|
90
|
+
}
|
|
91
|
+
if (ws) {
|
|
92
|
+
ws.close();
|
|
93
|
+
ws = null;
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
ready: null,
|
|
97
|
+
};
|
|
77
98
|
let resolveReady;
|
|
78
|
-
|
|
99
|
+
subscription.ready = new Promise((r) => {
|
|
79
100
|
resolveReady = r;
|
|
80
101
|
});
|
|
81
102
|
const connect = () => {
|
|
@@ -90,6 +111,8 @@ export class NchanClient {
|
|
|
90
111
|
onMessage(event.data);
|
|
91
112
|
};
|
|
92
113
|
ws.onopen = () => {
|
|
114
|
+
const isReconnect = !firstConnection;
|
|
115
|
+
firstConnection = false;
|
|
93
116
|
reconnectAttempts = 0;
|
|
94
117
|
// Clear any pending reconnect timer from previous disconnect
|
|
95
118
|
if (reconnectTimer) {
|
|
@@ -97,6 +120,9 @@ export class NchanClient {
|
|
|
97
120
|
reconnectTimer = null;
|
|
98
121
|
}
|
|
99
122
|
resolveReady();
|
|
123
|
+
if (isReconnect && subscription.onReconnect) {
|
|
124
|
+
subscription.onReconnect();
|
|
125
|
+
}
|
|
100
126
|
};
|
|
101
127
|
ws.onclose = () => {
|
|
102
128
|
if (!stopped) {
|
|
@@ -111,20 +137,7 @@ export class NchanClient {
|
|
|
111
137
|
};
|
|
112
138
|
};
|
|
113
139
|
connect();
|
|
114
|
-
return
|
|
115
|
-
ready,
|
|
116
|
-
stop: () => {
|
|
117
|
-
stopped = true;
|
|
118
|
-
if (reconnectTimer) {
|
|
119
|
-
clearTimeout(reconnectTimer);
|
|
120
|
-
reconnectTimer = null;
|
|
121
|
-
}
|
|
122
|
-
if (ws) {
|
|
123
|
-
ws.close();
|
|
124
|
-
ws = null;
|
|
125
|
-
}
|
|
126
|
-
},
|
|
127
|
-
};
|
|
140
|
+
return subscription;
|
|
128
141
|
}
|
|
129
142
|
}
|
|
130
143
|
//# sourceMappingURL=nchanclient.js.map
|
package/dist/nchanclient.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nchanclient.js","sourceRoot":"","sources":["../src/nchanclient.ts"],"names":[],"mappings":"AAEA,MAAM,KAAK,GAAG;IACZ,gBAAgB,EAAE,yBAAyB;IAC3C,kBAAkB,EAAE,2BAA2B;IAC/C,aAAa,EAAE,CAAC,OAAe,EAAE,EAAE,CAAC,kBAAkB,OAAO,EAAE;IAC/D,eAAe,EAAE,CAAC,OAAe,EAAE,EAAE,CAAC,oBAAoB,OAAO,EAAE;CAC3D,CAAC;
|
|
1
|
+
{"version":3,"file":"nchanclient.js","sourceRoot":"","sources":["../src/nchanclient.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -56,6 +56,16 @@ export interface ChallengeMessage {
|
|
|
56
56
|
readonly rematch?: RematchInfo;
|
|
57
57
|
meta?: Meta;
|
|
58
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* 1-to-1 public-broadcast chat message
|
|
61
|
+
*/
|
|
62
|
+
export interface ChatMessage {
|
|
63
|
+
messageType: "chat";
|
|
64
|
+
senderId: string;
|
|
65
|
+
recipientId: string;
|
|
66
|
+
text: string;
|
|
67
|
+
meta?: Meta;
|
|
68
|
+
}
|
|
59
69
|
/**
|
|
60
70
|
* Generic structure for table/game events
|
|
61
71
|
*/
|
|
@@ -93,12 +103,13 @@ export interface ActiveGame {
|
|
|
93
103
|
/**
|
|
94
104
|
* Union type for messages received via the lobby channel
|
|
95
105
|
*/
|
|
96
|
-
export type LobbyIncomingMessage = PresenceMessage | ChallengeMessage;
|
|
106
|
+
export type LobbyIncomingMessage = PresenceMessage | ChallengeMessage | ChatMessage;
|
|
97
107
|
/**
|
|
98
108
|
* Type guards
|
|
99
109
|
*/
|
|
100
110
|
export declare function isPresenceMessage(msg: any): msg is PresenceMessage;
|
|
101
111
|
export declare function isChallengeMessage(msg: any): msg is ChallengeMessage;
|
|
112
|
+
export declare function isChatMessage(msg: any): msg is ChatMessage;
|
|
102
113
|
/**
|
|
103
114
|
* Predicate: can the current user challenge this target?
|
|
104
115
|
* Returns true if target is not self, not in a game, and not seeking
|
package/dist/types.js
CHANGED
|
@@ -7,6 +7,9 @@ export function isPresenceMessage(msg) {
|
|
|
7
7
|
export function isChallengeMessage(msg) {
|
|
8
8
|
return msg?.messageType === "challenge";
|
|
9
9
|
}
|
|
10
|
+
export function isChatMessage(msg) {
|
|
11
|
+
return msg?.messageType === "chat";
|
|
12
|
+
}
|
|
10
13
|
/**
|
|
11
14
|
* Predicate: can the current user challenge this target?
|
|
12
15
|
* Returns true if target is not self, not in a game, and not seeking
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AA4GA;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAAQ;IACxC,OAAO,GAAG,EAAE,WAAW,KAAK,UAAU,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,GAAQ;IACzC,OAAO,GAAG,EAAE,WAAW,KAAK,WAAW,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,GAAQ;IACpC,OAAO,GAAG,EAAE,WAAW,KAAK,MAAM,CAAC;AACrC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,MAAuB,EAAE,aAAqB;IACzE,OAAO,MAAM,CAAC,MAAM,KAAK,aAAa,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;AAC5E,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,MAAuB,EAAE,cAAuB;IAC1E,OAAO,CAAC,CAAC,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,KAAK,cAAc,CAAC;AAC/D,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,KAAwB;IAClD,MAAM,OAAO,GAAG,IAAI,GAAG,EAAsB,CAAC;IAE9C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC/B,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE;oBACxB,OAAO,EAAE,IAAI,CAAC,OAAO;oBACrB,OAAO,EAAE,EAAE;oBACX,QAAQ,EAAE,IAAI,CAAC,QAAQ;iBACxB,CAAC,CAAC;YACL,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAE,CAAC,OAAO,CAAC,IAAI,CAAC;gBACtC,EAAE,EAAE,IAAI,CAAC,MAAM;gBACf,IAAI,EAAE,IAAI,CAAC,QAAQ;aACpB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;AACtC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAI,IAAY;IAC1C,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC;IAC7C,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAM,CAAC;IAC/B,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CAAC,gCAAgC,EAAE,CAAC,CAAC,CAAC;QACnD,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tailuge/messaging",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.13.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A stateful messaging library for Nchan-powered real-time applications.",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -51,10 +51,10 @@
|
|
|
51
51
|
"esbuild": "^0.27.4",
|
|
52
52
|
"http-server": "^14.1.1",
|
|
53
53
|
"jest": "30.3.0",
|
|
54
|
-
"oxlint": "^1.
|
|
54
|
+
"oxlint": "^1.57.0",
|
|
55
55
|
"testcontainers": "^11.13.0",
|
|
56
56
|
"ts-jest": "^29.4.6",
|
|
57
|
-
"typescript": "
|
|
57
|
+
"typescript": "^6.0.2",
|
|
58
58
|
"ws": "^8.20.0"
|
|
59
59
|
},
|
|
60
60
|
"browserslist": [
|