@tailuge/messaging 1.24.0 → 1.26.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/lobby.d.ts +1 -9
- package/dist/lobby.js +22 -50
- package/dist/lobby.js.map +1 -1
- package/dist/nchanclient.d.ts +1 -1
- package/dist/nchanclient.js +48 -24
- package/dist/nchanclient.js.map +1 -1
- package/dist/types.d.ts +3 -0
- package/dist/types.js.map +1 -1
- package/package.json +9 -7
package/dist/lobby.d.ts
CHANGED
|
@@ -3,8 +3,6 @@ import { PresenceMessage, ChallengeMessage, ChatMessage } from "./types";
|
|
|
3
3
|
import { Table } from "./table";
|
|
4
4
|
export interface LobbyOptions {
|
|
5
5
|
heartbeatInterval?: number;
|
|
6
|
-
pruneInterval?: number;
|
|
7
|
-
staleTtl?: number;
|
|
8
6
|
onReconnect?: () => void;
|
|
9
7
|
onLeave?: () => void;
|
|
10
8
|
}
|
|
@@ -23,13 +21,9 @@ export declare class Lobby {
|
|
|
23
21
|
private deduplicator;
|
|
24
22
|
private subscription;
|
|
25
23
|
private isJoined;
|
|
26
|
-
private cachedUsersList;
|
|
27
24
|
private heartbeatTimer?;
|
|
28
|
-
private pruneTimer?;
|
|
29
25
|
private presenceMessageCount;
|
|
30
26
|
private readonly heartbeatInterval;
|
|
31
|
-
private readonly pruneInterval;
|
|
32
|
-
private readonly staleTtl;
|
|
33
27
|
constructor(nchan: NchanClient, currentUser: PresenceMessage, options?: LobbyOptions);
|
|
34
28
|
/**
|
|
35
29
|
* Subscribe to incoming chat messages directed at the current user.
|
|
@@ -53,8 +47,6 @@ export declare class Lobby {
|
|
|
53
47
|
resumeHeartbeat(): void;
|
|
54
48
|
private startHeartbeat;
|
|
55
49
|
private stopHeartbeat;
|
|
56
|
-
private startPruning;
|
|
57
|
-
private stopPruning;
|
|
58
50
|
/**
|
|
59
51
|
* Emits the current list of online users whenever it changes.
|
|
60
52
|
*/
|
|
@@ -81,7 +73,7 @@ export declare class Lobby {
|
|
|
81
73
|
* Accept an incoming challenge.
|
|
82
74
|
* Returns the Table instance for the accepted game.
|
|
83
75
|
*/
|
|
84
|
-
acceptChallenge(userId: string, ruleType: string, tableId: string, options?: Record<string, string>, challengerName?: string): Promise<Table>;
|
|
76
|
+
acceptChallenge(userId: string, ruleType: string, tableId: string, options?: Record<string, string>, challengerName?: string, nextTurnId?: string): Promise<Table>;
|
|
85
77
|
/**
|
|
86
78
|
* Decline an incoming challenge.
|
|
87
79
|
*/
|
package/dist/lobby.js
CHANGED
|
@@ -17,11 +17,8 @@ export class Lobby {
|
|
|
17
17
|
this.pendingChallenges = [];
|
|
18
18
|
this.subscription = null;
|
|
19
19
|
this.isJoined = false;
|
|
20
|
-
this.cachedUsersList = null;
|
|
21
20
|
this.presenceMessageCount = 0;
|
|
22
21
|
this.heartbeatInterval = options.heartbeatInterval || 60000;
|
|
23
|
-
this.pruneInterval = options.pruneInterval || 30000;
|
|
24
|
-
this.staleTtl = options.staleTtl || 90000;
|
|
25
22
|
this.deduplicator = new ChallengeDeduplicator((msg) => {
|
|
26
23
|
this.pendingChallenges.push(msg);
|
|
27
24
|
this.challengeListeners.forEach((cb) => cb(msg));
|
|
@@ -49,7 +46,7 @@ export class Lobby {
|
|
|
49
46
|
async join() {
|
|
50
47
|
if (this.isJoined)
|
|
51
48
|
return;
|
|
52
|
-
this.subscription = this.nchan.subscribePresence((data) => {
|
|
49
|
+
this.subscription = this.nchan.subscribePresence(this.currentUser.userId, (data) => {
|
|
53
50
|
this.handleIncomingMessage(data);
|
|
54
51
|
});
|
|
55
52
|
this.subscription.onReconnect = () => {
|
|
@@ -61,16 +58,28 @@ export class Lobby {
|
|
|
61
58
|
}
|
|
62
59
|
else {
|
|
63
60
|
// Fallback: Re-broadcast presence state if no external orchestrator is handling it
|
|
64
|
-
this.nchan.publishPresence(this.currentUser).catch((_e) => {
|
|
61
|
+
this.nchan.publishPresence({ ...this.currentUser, clientTs: Date.now() }).catch((_e) => {
|
|
65
62
|
console.error("Failed to re-broadcast presence on reconnect:", _e);
|
|
66
63
|
});
|
|
67
64
|
}
|
|
68
65
|
};
|
|
69
66
|
await this.subscription.ready;
|
|
70
|
-
// Broadcast our own presence
|
|
71
|
-
|
|
67
|
+
// Broadcast our own presence with retry on failure (e.g. slow cold start)
|
|
68
|
+
for (let attempt = 1;; attempt++) {
|
|
69
|
+
try {
|
|
70
|
+
await this.nchan.publishPresence({
|
|
71
|
+
...this.currentUser,
|
|
72
|
+
clientTs: Date.now(),
|
|
73
|
+
});
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
catch (e) {
|
|
77
|
+
const delay = Math.min(Math.pow(2, attempt) * 4000, 30000);
|
|
78
|
+
console.warn(`[Lobby] Initial presence publish failed (attempt ${attempt}), retrying in ${delay}ms:`, e);
|
|
79
|
+
await new Promise((r) => setTimeout(r, delay));
|
|
80
|
+
}
|
|
81
|
+
}
|
|
72
82
|
this.startHeartbeat();
|
|
73
|
-
this.startPruning();
|
|
74
83
|
this.isJoined = true;
|
|
75
84
|
}
|
|
76
85
|
/**
|
|
@@ -103,33 +112,6 @@ export class Lobby {
|
|
|
103
112
|
this.heartbeatTimer = undefined;
|
|
104
113
|
}
|
|
105
114
|
}
|
|
106
|
-
startPruning() {
|
|
107
|
-
this.stopPruning();
|
|
108
|
-
this.pruneTimer = setInterval(() => {
|
|
109
|
-
const now = Date.now();
|
|
110
|
-
let changed = false;
|
|
111
|
-
for (const [userId, user] of this.users.entries()) {
|
|
112
|
-
if (userId === this.currentUser.userId)
|
|
113
|
-
continue;
|
|
114
|
-
const lastSeen = user.meta?.ts || 0;
|
|
115
|
-
if (now - lastSeen > this.staleTtl) {
|
|
116
|
-
this.users.delete(userId);
|
|
117
|
-
changed = true;
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
if (changed) {
|
|
121
|
-
this.cachedUsersList = null;
|
|
122
|
-
this.notifyListeners();
|
|
123
|
-
}
|
|
124
|
-
}, this.pruneInterval);
|
|
125
|
-
this.pruneTimer.unref?.();
|
|
126
|
-
}
|
|
127
|
-
stopPruning() {
|
|
128
|
-
if (this.pruneTimer) {
|
|
129
|
-
clearInterval(this.pruneTimer);
|
|
130
|
-
this.pruneTimer = undefined;
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
115
|
/**
|
|
134
116
|
* Emits the current list of online users whenever it changes.
|
|
135
117
|
*/
|
|
@@ -164,6 +146,7 @@ export class Lobby {
|
|
|
164
146
|
await this.nchan.publishPresence({
|
|
165
147
|
...this.currentUser,
|
|
166
148
|
...update,
|
|
149
|
+
clientTs: Date.now(),
|
|
167
150
|
});
|
|
168
151
|
}
|
|
169
152
|
/**
|
|
@@ -187,7 +170,7 @@ export class Lobby {
|
|
|
187
170
|
* Accept an incoming challenge.
|
|
188
171
|
* Returns the Table instance for the accepted game.
|
|
189
172
|
*/
|
|
190
|
-
async acceptChallenge(userId, ruleType, tableId, options, challengerName) {
|
|
173
|
+
async acceptChallenge(userId, ruleType, tableId, options, challengerName, nextTurnId) {
|
|
191
174
|
await this.nchan.publishChallenge({
|
|
192
175
|
type: "accept",
|
|
193
176
|
challengerId: userId,
|
|
@@ -196,6 +179,7 @@ export class Lobby {
|
|
|
196
179
|
ruleType,
|
|
197
180
|
tableId,
|
|
198
181
|
options,
|
|
182
|
+
nextTurnId,
|
|
199
183
|
});
|
|
200
184
|
// Automatically update our presence to show we've joined the table
|
|
201
185
|
await this.updatePresence({ tableId });
|
|
@@ -240,19 +224,14 @@ export class Lobby {
|
|
|
240
224
|
*/
|
|
241
225
|
async leave(options = {}) {
|
|
242
226
|
this.stopHeartbeat();
|
|
243
|
-
this.stopPruning();
|
|
244
227
|
this.subscription?.stop();
|
|
245
228
|
try {
|
|
246
|
-
await this.nchan.publishPresence({
|
|
247
|
-
...this.currentUser,
|
|
248
|
-
type: "leave",
|
|
249
|
-
}, { keepalive: options.isTeardown });
|
|
229
|
+
await this.nchan.publishPresence({ ...this.currentUser, type: "leave", clientTs: Date.now() }, { keepalive: options.isTeardown });
|
|
250
230
|
}
|
|
251
231
|
catch (e) {
|
|
252
232
|
console.error("Error leaving lobby:", e);
|
|
253
233
|
}
|
|
254
234
|
this.users.clear();
|
|
255
|
-
this.cachedUsersList = null;
|
|
256
235
|
this.pendingChallenges = [];
|
|
257
236
|
this.deduplicator.clear();
|
|
258
237
|
this.presenceMessageCount = 0;
|
|
@@ -287,13 +266,11 @@ export class Lobby {
|
|
|
287
266
|
if (msg.type === "leave") {
|
|
288
267
|
if (existing) {
|
|
289
268
|
this.users.delete(msg.userId);
|
|
290
|
-
this.cachedUsersList = null;
|
|
291
269
|
this.notifyListeners();
|
|
292
270
|
}
|
|
293
271
|
}
|
|
294
272
|
else if (msg.type === "join") {
|
|
295
273
|
this.users.set(msg.userId, msg);
|
|
296
|
-
this.cachedUsersList = null;
|
|
297
274
|
this.notifyListeners();
|
|
298
275
|
}
|
|
299
276
|
else {
|
|
@@ -301,7 +278,6 @@ export class Lobby {
|
|
|
301
278
|
const changed = !existing || this.hasMeaningfulChange(existing, msg);
|
|
302
279
|
this.users.set(msg.userId, msg);
|
|
303
280
|
if (changed) {
|
|
304
|
-
this.cachedUsersList = null;
|
|
305
281
|
this.notifyListeners();
|
|
306
282
|
}
|
|
307
283
|
}
|
|
@@ -320,11 +296,7 @@ export class Lobby {
|
|
|
320
296
|
this.listeners.forEach((cb) => cb(list));
|
|
321
297
|
}
|
|
322
298
|
getUsersList() {
|
|
323
|
-
|
|
324
|
-
return this.cachedUsersList;
|
|
325
|
-
}
|
|
326
|
-
this.cachedUsersList = Array.from(this.users.values()).sort((a, b) => a.userName.localeCompare(b.userName));
|
|
327
|
-
return this.cachedUsersList;
|
|
299
|
+
return Array.from(this.users.values()).sort((a, b) => a.userName.localeCompare(b.userName));
|
|
328
300
|
}
|
|
329
301
|
hasMeaningfulChange(oldMsg, nextMsg) {
|
|
330
302
|
return (oldMsg.userName !== nextMsg.userName ||
|
package/dist/lobby.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lobby.js","sourceRoot":"","sources":["../src/lobby.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,YAAY,GAEb,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"lobby.js","sourceRoot":"","sources":["../src/lobby.ts"],"names":[],"mappings":"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"}
|
package/dist/nchanclient.d.ts
CHANGED
|
@@ -27,7 +27,7 @@ export declare class NchanClient {
|
|
|
27
27
|
publishTable<T>(tableId: string, message: Omit<TableMessage<T>, "senderId">, senderId: string, options?: {
|
|
28
28
|
keepalive?: boolean;
|
|
29
29
|
}): Promise<void>;
|
|
30
|
-
subscribePresence(onMessage: (data: string) => void): Subscription;
|
|
30
|
+
subscribePresence(userId: string, onMessage: (data: string) => void): Subscription;
|
|
31
31
|
subscribeTable(tableId: string, onMessage: (data: string) => void): Subscription;
|
|
32
32
|
private subscribe;
|
|
33
33
|
}
|
package/dist/nchanclient.js
CHANGED
|
@@ -48,12 +48,21 @@ export class NchanClient {
|
|
|
48
48
|
return; // Successfully queued by the browser
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
51
|
+
const controller = new AbortController();
|
|
52
|
+
const timeout = setTimeout(() => controller.abort(), 20000);
|
|
53
|
+
let response;
|
|
54
|
+
try {
|
|
55
|
+
response = await fetch(url, {
|
|
56
|
+
method: "POST",
|
|
57
|
+
headers: { "Content-Type": "application/json" },
|
|
58
|
+
body,
|
|
59
|
+
keepalive: options.keepalive,
|
|
60
|
+
signal: controller.signal,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
finally {
|
|
64
|
+
clearTimeout(timeout);
|
|
65
|
+
}
|
|
57
66
|
if (!response.ok) {
|
|
58
67
|
throw new Error(`Publish failed: ${response.status}`);
|
|
59
68
|
}
|
|
@@ -84,14 +93,16 @@ export class NchanClient {
|
|
|
84
93
|
}, options);
|
|
85
94
|
}
|
|
86
95
|
// Subscribing
|
|
87
|
-
subscribePresence(onMessage) {
|
|
88
|
-
|
|
96
|
+
subscribePresence(userId, onMessage) {
|
|
97
|
+
const path = `${PATHS.PRESENCE_SUBSCRIBE}?uid=${encodeURIComponent(userId)}`;
|
|
98
|
+
return this.subscribe(path, onMessage);
|
|
89
99
|
}
|
|
90
100
|
subscribeTable(tableId, onMessage) {
|
|
91
101
|
return this.subscribe(PATHS.TABLE_SUBSCRIBE(tableId), onMessage);
|
|
92
102
|
}
|
|
93
103
|
subscribe(path, onMessage) {
|
|
94
104
|
const url = this.getWsUrl(path);
|
|
105
|
+
const ts = () => new Date().toISOString().slice(11, 23); // HH:MM:SS.mmm
|
|
95
106
|
let ws = null;
|
|
96
107
|
let stopped = false;
|
|
97
108
|
let reconnectAttempts = 0;
|
|
@@ -99,6 +110,8 @@ export class NchanClient {
|
|
|
99
110
|
const maxReconnectDelay = 60000;
|
|
100
111
|
let reconnectTimer = null;
|
|
101
112
|
let firstConnection = true;
|
|
113
|
+
const CONNECTION_TIMEOUT_MS = 20000;
|
|
114
|
+
let connectionTimeoutTimer = null;
|
|
102
115
|
const subscription = {
|
|
103
116
|
stop: () => {
|
|
104
117
|
stopped = true;
|
|
@@ -106,6 +119,10 @@ export class NchanClient {
|
|
|
106
119
|
clearTimeout(reconnectTimer);
|
|
107
120
|
reconnectTimer = null;
|
|
108
121
|
}
|
|
122
|
+
if (connectionTimeoutTimer) {
|
|
123
|
+
clearTimeout(connectionTimeoutTimer);
|
|
124
|
+
connectionTimeoutTimer = null;
|
|
125
|
+
}
|
|
109
126
|
if (ws) {
|
|
110
127
|
ws.close();
|
|
111
128
|
ws = null;
|
|
@@ -117,8 +134,6 @@ export class NchanClient {
|
|
|
117
134
|
subscription.ready = new Promise((r) => {
|
|
118
135
|
resolveReady = r;
|
|
119
136
|
});
|
|
120
|
-
const INITIAL_TIMEOUT_MS = 10000;
|
|
121
|
-
let initialTimeoutTimer = null;
|
|
122
137
|
const connect = () => {
|
|
123
138
|
if (stopped)
|
|
124
139
|
return;
|
|
@@ -126,15 +141,16 @@ export class NchanClient {
|
|
|
126
141
|
resolveReady();
|
|
127
142
|
return;
|
|
128
143
|
}
|
|
129
|
-
console.log(`[NchanClient] Connecting to ${url} (attempt ${reconnectAttempts + 1})`);
|
|
144
|
+
console.log(`[NchanClient ${ts()}] Connecting to ${url} (attempt ${reconnectAttempts + 1})`);
|
|
130
145
|
ws = new globalThis.WebSocket(url);
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
initialTimeoutTimer = setTimeout(() => {
|
|
134
|
-
console.warn(`[NchanClient] Initial connection to ${url} timed out after ${INITIAL_TIMEOUT_MS}ms`);
|
|
135
|
-
}, INITIAL_TIMEOUT_MS);
|
|
136
|
-
initialTimeoutTimer.unref?.();
|
|
146
|
+
if (connectionTimeoutTimer) {
|
|
147
|
+
clearTimeout(connectionTimeoutTimer);
|
|
137
148
|
}
|
|
149
|
+
connectionTimeoutTimer = setTimeout(() => {
|
|
150
|
+
console.warn(`[NchanClient ${ts()}] Connection to ${url} timed out after ${CONNECTION_TIMEOUT_MS}ms, forcing reconnect`);
|
|
151
|
+
ws?.close();
|
|
152
|
+
}, CONNECTION_TIMEOUT_MS);
|
|
153
|
+
connectionTimeoutTimer.unref?.();
|
|
138
154
|
ws.onmessage = (event) => {
|
|
139
155
|
onMessage(event.data);
|
|
140
156
|
};
|
|
@@ -146,28 +162,36 @@ export class NchanClient {
|
|
|
146
162
|
clearTimeout(reconnectTimer);
|
|
147
163
|
reconnectTimer = null;
|
|
148
164
|
}
|
|
149
|
-
if (
|
|
150
|
-
clearTimeout(
|
|
151
|
-
|
|
165
|
+
if (connectionTimeoutTimer) {
|
|
166
|
+
clearTimeout(connectionTimeoutTimer);
|
|
167
|
+
connectionTimeoutTimer = null;
|
|
152
168
|
}
|
|
153
|
-
console.log(`[NchanClient] Connected to ${url}`);
|
|
169
|
+
console.log(`[NchanClient ${ts()}] Connected to ${url}`);
|
|
154
170
|
resolveReady();
|
|
155
171
|
if (isReconnect && subscription.onReconnect) {
|
|
156
172
|
subscription.onReconnect();
|
|
157
173
|
}
|
|
158
174
|
};
|
|
159
175
|
ws.onclose = (event) => {
|
|
160
|
-
console.log(`[NchanClient] Connection closed: ${url} (code=${event.code}, reason="${event.reason}", wasClean=${event.wasClean})`);
|
|
176
|
+
console.log(`[NchanClient ${ts()}] Connection closed: ${url} (code=${event.code}, reason="${event.reason}", wasClean=${event.wasClean})`);
|
|
177
|
+
if (connectionTimeoutTimer) {
|
|
178
|
+
clearTimeout(connectionTimeoutTimer);
|
|
179
|
+
connectionTimeoutTimer = null;
|
|
180
|
+
}
|
|
161
181
|
if (!stopped) {
|
|
182
|
+
if (reconnectAttempts >= 10) {
|
|
183
|
+
console.error(`[NchanClient ${ts()}] Max reconnect attempts reached for ${url}, giving up`);
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
162
186
|
const delay = Math.min(Math.pow(2, reconnectAttempts) * initialReconnectDelay, maxReconnectDelay);
|
|
163
187
|
reconnectAttempts++;
|
|
164
|
-
console.log(`[NchanClient] Reconnecting in ${delay}ms (attempt ${reconnectAttempts})`);
|
|
188
|
+
console.log(`[NchanClient ${ts()}] Reconnecting in ${delay}ms (attempt ${reconnectAttempts})`);
|
|
165
189
|
reconnectTimer = setTimeout(connect, delay);
|
|
166
190
|
reconnectTimer.unref?.();
|
|
167
191
|
}
|
|
168
192
|
};
|
|
169
193
|
ws.onerror = (event) => {
|
|
170
|
-
console.error(`[NchanClient] WebSocket error on ${url}:`, event);
|
|
194
|
+
console.error(`[NchanClient ${ts()}] WebSocket error on ${url}:`, event);
|
|
171
195
|
ws?.close();
|
|
172
196
|
};
|
|
173
197
|
};
|
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;AAQX,MAAM,OAAO,WAAW;IAItB,YAAY,MAAc;QACxB,gDAAgD;QAChD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAExC,oEAAoE;QACpE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACjC,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;gBAClC,yCAAyC;gBACzC,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,sBAAsB;gBACjE,IAAI,CAAC,MAAM,GAAG,GAAG,QAAQ,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC;YAC9C,CAAC;iBAAM,CAAC;gBACN,wCAAwC;gBACxC,IAAI,CAAC,MAAM,GAAG,UAAU,IAAI,CAAC,MAAM,EAAE,CAAC;YACxC,CAAC;QACH,CAAC;IACH,CAAC;IAED;;OAEG;IACH,UAAU,CAAC,OAAe;QACxB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAEO,QAAQ,CAAC,IAAY;QAC3B,2CAA2C;QAC3C,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,IAAI,CAAC;IACnD,CAAC;IAEO,UAAU,CAAC,IAAY;QAC7B,OAAO,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;IAC5B,CAAC;IAEO,KAAK,CAAC,OAAO,CACnB,IAAY,EACZ,OAAY,EACZ,UAAmC,EAAE;QAErC,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAElC,kCAAkC;QAClC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,OAAO,CAAC,IAAI,GAAG,EAAE,GAAG,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC;QAC5D,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAErC,qDAAqD;QACrD,IAAI,OAAO,CAAC,SAAS,IAAI,OAAO,SAAS,KAAK,WAAW,IAAI,SAAS,CAAC,UAAU,EAAE,CAAC;YAClF,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC,CAAC;YAC5D,IAAI,SAAS,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,CAAC;gBACpC,OAAO,CAAC,qCAAqC;YAC/C,CAAC;QACH,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;
|
|
1
|
+
{"version":3,"file":"nchanclient.js","sourceRoot":"","sources":["../src/nchanclient.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -33,6 +33,8 @@ export interface PresenceMessage {
|
|
|
33
33
|
meta?: Meta;
|
|
34
34
|
tableId?: string;
|
|
35
35
|
isSpectator?: boolean;
|
|
36
|
+
isLeaving?: boolean;
|
|
37
|
+
clientTs?: number;
|
|
36
38
|
}
|
|
37
39
|
/**
|
|
38
40
|
* Peer-to-peer challenge request
|
|
@@ -46,6 +48,7 @@ export interface ChallengeMessage {
|
|
|
46
48
|
ruleType: string;
|
|
47
49
|
tableId?: string;
|
|
48
50
|
readonly options?: Record<string, string>;
|
|
51
|
+
nextTurnId?: string;
|
|
49
52
|
meta?: Meta;
|
|
50
53
|
}
|
|
51
54
|
/**
|
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":"AAyGA;;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,CAAC,MAAM,CAAC,WAAW,IAAI,MAAM,CAAC,OAAO,KAAK,cAAc,CAAC;AACtF,CAAC;AAOD,MAAM,UAAU,UAAU,CAAC,IAAqB;IAC9C,IAAI,CAAC,IAAI,CAAC,OAAO;QAAE,OAAO,WAAW,CAAC;IACtC,IAAI,IAAI,CAAC,WAAW;QAAE,OAAO,YAAY,CAAC;IAC1C,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,IAAqB;IAC7C,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC;AACvB,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.26.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A stateful messaging library for Nchan-powered real-time applications.",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -19,13 +19,15 @@
|
|
|
19
19
|
"scripts": {
|
|
20
20
|
"test": "jest --config test/jest.config.cjs --verbose",
|
|
21
21
|
"coverage": "jest --config test/jest.config.cjs --coverage",
|
|
22
|
-
"playwright": "npm run docker:build && npx playwright test",
|
|
22
|
+
"playwright": "npm run docker:build && npx playwright test --workers=1",
|
|
23
23
|
"playwright:rematch": "npm run docker:build && npx playwright test playwright/lobby-rematch.spec.ts",
|
|
24
|
+
"playwright:e2e": "npm run docker:build && npx playwright test playwright/e2e*.spec.ts --workers=1",
|
|
25
|
+
"playwright:new": "npm run docker:build && npx playwright test playwright/iframee2e.spec.ts --workers=1",
|
|
24
26
|
"test:debug": "npm run playwright",
|
|
25
27
|
"clientbump": "node scripts/clientbump.mjs",
|
|
26
28
|
"lint": "tsc --noEmit && npx oxlint src test",
|
|
27
29
|
"prettify": "npx oxfmt src test",
|
|
28
|
-
"build:lit": "npx esbuild src/client/lobby.js --bundle --minify --outfile=docker/html/lobby.js && cp src/client/*.html docker/html/ && cp src/client/favicon.ico src/client/robots.txt docker/html/ 2>/dev/null || true && mkdir -p docker/html/assets && cp src/client/assets/*.png docker/html/assets/ 2>/dev/null || true",
|
|
30
|
+
"build:lit": "npx esbuild src/client/lobby.js --bundle --minify --outfile=docker/html/lobby.js && cp src/client/*.html docker/html/ && cp src/client/favicon.ico src/client/robots.txt src/client/sitemap.xml docker/html/ 2>/dev/null || true && mkdir -p docker/html/assets && cp src/client/assets/*.png docker/html/assets/ 2>/dev/null || true",
|
|
29
31
|
"crossdeploy": "npx esbuild src/client/lobby.js --bundle --minify --outfile=../billiards/dist/lobby.js && cp src/client/lobby.html ../billiards/dist/ && cp src/client/assets/*.png ../billiards/dist/assets/",
|
|
30
32
|
"crossdeployv": "cp docker/html/lobby.js ../scoreboard/public/ && cp src/client/lobby.html ../scoreboard/public/ && cp src/client/assets/*.png ../scoreboard/public/assets/",
|
|
31
33
|
"build": "tsc --declaration && node scripts/add-js-extensions.js && npx esbuild src/index.ts --bundle --format=esm --outfile=docker/html/messaging.js && npm run build:lit",
|
|
@@ -48,13 +50,13 @@
|
|
|
48
50
|
"author": "tailuge",
|
|
49
51
|
"license": "GPL-3.0",
|
|
50
52
|
"devDependencies": {
|
|
51
|
-
"@playwright/test": "^1.
|
|
53
|
+
"@playwright/test": "^1.61.0",
|
|
52
54
|
"@types/jest": "30.0.0",
|
|
53
55
|
"@types/ws": "^8.18.1",
|
|
54
|
-
"esbuild": "^0.28.
|
|
56
|
+
"esbuild": "^0.28.1",
|
|
55
57
|
"jest": "^30.4.2",
|
|
56
|
-
"oxlint": "^1.
|
|
57
|
-
"testcontainers": "
|
|
58
|
+
"oxlint": "^1.70.0",
|
|
59
|
+
"testcontainers": "9.12.0",
|
|
58
60
|
"ts-jest": "^29.4.11",
|
|
59
61
|
"typescript": "^6.0.3",
|
|
60
62
|
"ws": "^8.21.0"
|