@tailuge/messaging 1.37.0 → 1.39.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/dist/table.d.ts +6 -0
- package/dist/table.js +29 -1
- package/dist/table.js.map +1 -1
- package/package.json +3 -3
package/dist/table.d.ts
CHANGED
|
@@ -16,12 +16,14 @@ export declare class Table<T = any> {
|
|
|
16
16
|
private messageListeners;
|
|
17
17
|
private spectatorListeners;
|
|
18
18
|
private opponentLeftListeners;
|
|
19
|
+
private opponentRejoinedListeners;
|
|
19
20
|
opponentLeft: boolean;
|
|
20
21
|
readonly bothJoined: Promise<void>;
|
|
21
22
|
private resolveBothJoined;
|
|
22
23
|
private bothJoinedListeners;
|
|
23
24
|
private bothJoinedResolved;
|
|
24
25
|
private seenIds;
|
|
26
|
+
private preJoinQueue;
|
|
25
27
|
constructor(nchan: NchanClient, tableId: string, userId: string, lobby?: Lobby | undefined, isSpectator?: boolean, onMessage?: (event: TableMessage<T>) => void, onBothJoined?: () => void);
|
|
26
28
|
/**
|
|
27
29
|
* Initializes the table by subscribing to its specific channel.
|
|
@@ -35,6 +37,10 @@ export declare class Table<T = any> {
|
|
|
35
37
|
* Subscribe to opponent departure (explicit leave or timeout).
|
|
36
38
|
*/
|
|
37
39
|
onOpponentLeft(callback: () => void): void;
|
|
40
|
+
/**
|
|
41
|
+
* Subscribe to opponent rejoin.
|
|
42
|
+
*/
|
|
43
|
+
onOpponentRejoined(callback: () => void): void;
|
|
38
44
|
/**
|
|
39
45
|
* Subscribe to changes in the spectator list.
|
|
40
46
|
* Note: In a real implementation, this would track presence messages on the table channel.
|
package/dist/table.js
CHANGED
|
@@ -15,17 +15,26 @@ export class Table {
|
|
|
15
15
|
this.messageListeners = [];
|
|
16
16
|
this.spectatorListeners = [];
|
|
17
17
|
this.opponentLeftListeners = [];
|
|
18
|
+
this.opponentRejoinedListeners = [];
|
|
18
19
|
this.opponentLeft = false;
|
|
19
20
|
this.bothJoinedListeners = [];
|
|
20
21
|
this.bothJoinedResolved = false;
|
|
21
22
|
this.seenIds = new Set();
|
|
23
|
+
this.preJoinQueue = [];
|
|
22
24
|
this.bothJoined = new Promise((resolve) => {
|
|
23
25
|
this.resolveBothJoined = () => {
|
|
24
26
|
if (this.bothJoinedResolved)
|
|
25
27
|
return;
|
|
26
28
|
this.bothJoinedResolved = true;
|
|
27
|
-
|
|
29
|
+
// Fire onBothJoined callbacks FIRST, so consumers' flags are set
|
|
30
|
+
// before we drain queued messages into onMessage.
|
|
28
31
|
this.bothJoinedListeners.forEach((cb) => cb());
|
|
32
|
+
// Now drain queued messages synchronously. By this point bothJoinedResolved
|
|
33
|
+
// is true and all onBothJoined callbacks have run, so any consumer checking
|
|
34
|
+
// a flag set in onBothJoined will see it as set when onMessage fires.
|
|
35
|
+
const queued = this.preJoinQueue.splice(0);
|
|
36
|
+
queued.forEach((msg) => this.messageListeners.forEach((cb) => cb(msg)));
|
|
37
|
+
resolve();
|
|
29
38
|
};
|
|
30
39
|
});
|
|
31
40
|
if (onMessage) {
|
|
@@ -63,6 +72,12 @@ export class Table {
|
|
|
63
72
|
callback();
|
|
64
73
|
}
|
|
65
74
|
}
|
|
75
|
+
/**
|
|
76
|
+
* Subscribe to opponent rejoin.
|
|
77
|
+
*/
|
|
78
|
+
onOpponentRejoined(callback) {
|
|
79
|
+
this.opponentRejoinedListeners.push(callback);
|
|
80
|
+
}
|
|
66
81
|
/**
|
|
67
82
|
* Subscribe to changes in the spectator list.
|
|
68
83
|
* Note: In a real implementation, this would track presence messages on the table channel.
|
|
@@ -96,6 +111,7 @@ export class Table {
|
|
|
96
111
|
this.messageListeners = [];
|
|
97
112
|
this.spectatorListeners = [];
|
|
98
113
|
this.opponentLeftListeners = [];
|
|
114
|
+
this.opponentRejoinedListeners = [];
|
|
99
115
|
this.isJoined = false;
|
|
100
116
|
}
|
|
101
117
|
handleIncomingMessage(data) {
|
|
@@ -114,10 +130,22 @@ export class Table {
|
|
|
114
130
|
if (this.seenIds.size >= 2) {
|
|
115
131
|
this.resolveBothJoined();
|
|
116
132
|
}
|
|
133
|
+
// Detect rejoin if it is the opponent, bothJoined has resolved, and opponentLeft is currently true
|
|
134
|
+
if (this.bothJoinedResolved && joinedId !== this.userId && this.opponentLeft) {
|
|
135
|
+
this.opponentLeft = false;
|
|
136
|
+
this.opponentRejoinedListeners.forEach((cb) => cb());
|
|
137
|
+
}
|
|
117
138
|
}
|
|
118
139
|
return; // Filter out internal "joined" messages from generic onMessage listeners
|
|
119
140
|
}
|
|
120
141
|
// Notify message listeners
|
|
142
|
+
if (!this.isSpectator && !this.bothJoinedResolved) {
|
|
143
|
+
// Queue messages that arrive before both players have joined.
|
|
144
|
+
// They will be drained synchronously when resolveBothJoined() fires,
|
|
145
|
+
// guaranteeing bothJoinedResolved is true before any onMessage callback runs.
|
|
146
|
+
this.preJoinQueue.push(msg);
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
121
149
|
this.messageListeners.forEach((cb) => cb(msg));
|
|
122
150
|
}
|
|
123
151
|
notifyOpponentLeft() {
|
package/dist/table.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"table.js","sourceRoot":"","sources":["../src/table.ts"],"names":[],"mappings":"AACA,OAAO,EAAgC,qBAAqB,EAAE,YAAY,EAAmB,MAAM,SAAS,CAAC;AAG7G;;;GAGG;AACH,MAAM,OAAO,KAAK;
|
|
1
|
+
{"version":3,"file":"table.js","sourceRoot":"","sources":["../src/table.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tailuge/messaging",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.39.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A stateful messaging library for Nchan-powered real-time applications.",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -50,12 +50,12 @@
|
|
|
50
50
|
"author": "tailuge",
|
|
51
51
|
"license": "GPL-3.0",
|
|
52
52
|
"devDependencies": {
|
|
53
|
-
"@playwright/test": "^1.62.
|
|
53
|
+
"@playwright/test": "^1.62.1",
|
|
54
54
|
"@types/jest": "^30.0.0",
|
|
55
55
|
"@types/ws": "^8.18.1",
|
|
56
56
|
"esbuild": "^0.28.1",
|
|
57
57
|
"jest": "^30.4.2",
|
|
58
|
-
"oxlint": "^1.
|
|
58
|
+
"oxlint": "^1.76.0",
|
|
59
59
|
"testcontainers": "9.12.0",
|
|
60
60
|
"ts-jest": "^29.4.12",
|
|
61
61
|
"ts-node": "^10.9.2",
|