@tailuge/messaging 1.23.0 → 1.25.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 +1 -14
- package/dist/lobby.d.ts +7 -2
- package/dist/lobby.js +50 -9
- package/dist/lobby.js.map +1 -1
- package/dist/nchanclient.d.ts +1 -1
- package/dist/nchanclient.js +55 -13
- package/dist/nchanclient.js.map +1 -1
- package/dist/types.d.ts +0 -16
- package/dist/types.js.map +1 -1
- package/package.json +6 -6
package/MESSAGING_SPEC.md
CHANGED
|
@@ -69,7 +69,7 @@ interface Lobby {
|
|
|
69
69
|
* Challenge another user to a game.
|
|
70
70
|
* Returns the ID of the table created for the challenge.
|
|
71
71
|
*/
|
|
72
|
-
challenge(userId: string, ruleType: string
|
|
72
|
+
challenge(userId: string, ruleType: string): Promise<string>;
|
|
73
73
|
|
|
74
74
|
/**
|
|
75
75
|
* Accept an incoming challenge.
|
|
@@ -231,18 +231,6 @@ await lobby.updatePresence({ tableId: "table-123" });
|
|
|
231
231
|
await lobby.updatePresence({ tableId: undefined });
|
|
232
232
|
```
|
|
233
233
|
|
|
234
|
-
### `RematchInfo`
|
|
235
|
-
|
|
236
|
-
Context about a previous game for rematch challenges.
|
|
237
|
-
|
|
238
|
-
```typescript
|
|
239
|
-
interface RematchInfo {
|
|
240
|
-
readonly lastScores: { readonly userId: string; readonly score: number }[];
|
|
241
|
-
readonly isRematch: boolean;
|
|
242
|
-
readonly nextTurnId: string; // The ID of the player who should break/go first
|
|
243
|
-
}
|
|
244
|
-
```
|
|
245
|
-
|
|
246
234
|
### `ChallengeMessage`
|
|
247
235
|
|
|
248
236
|
Represents a peer-to-peer challenge request.
|
|
@@ -269,7 +257,6 @@ interface ChallengeMessage {
|
|
|
269
257
|
challengeeId: string; // Always the person being challenged, across all message types
|
|
270
258
|
ruleType: string;
|
|
271
259
|
tableId?: string; // Optional: table created by challenger
|
|
272
|
-
rematch?: RematchInfo; // Optional: context about a previous game
|
|
273
260
|
meta?: Meta; // Server-enriched metadata (received messages only)
|
|
274
261
|
}
|
|
275
262
|
```
|
package/dist/lobby.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { NchanClient } from "./nchanclient";
|
|
2
|
-
import { PresenceMessage, ChallengeMessage,
|
|
2
|
+
import { PresenceMessage, ChallengeMessage, ChatMessage } from "./types";
|
|
3
3
|
import { Table } from "./table";
|
|
4
4
|
export interface LobbyOptions {
|
|
5
5
|
heartbeatInterval?: number;
|
|
@@ -23,6 +23,7 @@ export declare class Lobby {
|
|
|
23
23
|
private deduplicator;
|
|
24
24
|
private subscription;
|
|
25
25
|
private isJoined;
|
|
26
|
+
private cachedUsersList;
|
|
26
27
|
private heartbeatTimer?;
|
|
27
28
|
private pruneTimer?;
|
|
28
29
|
private presenceMessageCount;
|
|
@@ -75,7 +76,7 @@ export declare class Lobby {
|
|
|
75
76
|
* Challenge another user to a game.
|
|
76
77
|
* Returns the ID of the table created for the challenge.
|
|
77
78
|
*/
|
|
78
|
-
challenge(userId: string, ruleType: string,
|
|
79
|
+
challenge(userId: string, ruleType: string, options?: Record<string, string>): Promise<string>;
|
|
79
80
|
/**
|
|
80
81
|
* Accept an incoming challenge.
|
|
81
82
|
* Returns the Table instance for the accepted game.
|
|
@@ -105,10 +106,14 @@ export declare class Lobby {
|
|
|
105
106
|
* Handles incoming presence updates.
|
|
106
107
|
* Note: Nchan guarantees ordered delivery, so we don't need to check meta.ts for ordering.
|
|
107
108
|
* The last message received for each userId will be the current state.
|
|
109
|
+
*
|
|
110
|
+
* We deduplicate notifications here because the Lobby has domain knowledge of which
|
|
111
|
+
* fields are "meaningful" (e.g. userName, tableId) vs "noise" (e.g. meta.ts heartbeats).
|
|
108
112
|
*/
|
|
109
113
|
private handlePresenceUpdate;
|
|
110
114
|
private handleChallenge;
|
|
111
115
|
private handleChat;
|
|
112
116
|
private notifyListeners;
|
|
113
117
|
private getUsersList;
|
|
118
|
+
private hasMeaningfulChange;
|
|
114
119
|
}
|
package/dist/lobby.js
CHANGED
|
@@ -17,6 +17,7 @@ export class Lobby {
|
|
|
17
17
|
this.pendingChallenges = [];
|
|
18
18
|
this.subscription = null;
|
|
19
19
|
this.isJoined = false;
|
|
20
|
+
this.cachedUsersList = null;
|
|
20
21
|
this.presenceMessageCount = 0;
|
|
21
22
|
this.heartbeatInterval = options.heartbeatInterval || 60000;
|
|
22
23
|
this.pruneInterval = options.pruneInterval || 30000;
|
|
@@ -48,7 +49,7 @@ export class Lobby {
|
|
|
48
49
|
async join() {
|
|
49
50
|
if (this.isJoined)
|
|
50
51
|
return;
|
|
51
|
-
this.subscription = this.nchan.subscribePresence((data) => {
|
|
52
|
+
this.subscription = this.nchan.subscribePresence(this.currentUser.userId, (data) => {
|
|
52
53
|
this.handleIncomingMessage(data);
|
|
53
54
|
});
|
|
54
55
|
this.subscription.onReconnect = () => {
|
|
@@ -66,8 +67,18 @@ export class Lobby {
|
|
|
66
67
|
}
|
|
67
68
|
};
|
|
68
69
|
await this.subscription.ready;
|
|
69
|
-
// Broadcast our own presence
|
|
70
|
-
|
|
70
|
+
// Broadcast our own presence with retry on failure (e.g. slow cold start)
|
|
71
|
+
for (let attempt = 1;; attempt++) {
|
|
72
|
+
try {
|
|
73
|
+
await this.nchan.publishPresence(this.currentUser);
|
|
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
|
+
}
|
|
71
82
|
this.startHeartbeat();
|
|
72
83
|
this.startPruning();
|
|
73
84
|
this.isJoined = true;
|
|
@@ -110,13 +121,14 @@ export class Lobby {
|
|
|
110
121
|
for (const [userId, user] of this.users.entries()) {
|
|
111
122
|
if (userId === this.currentUser.userId)
|
|
112
123
|
continue;
|
|
113
|
-
const lastSeen = user.meta
|
|
124
|
+
const lastSeen = user.meta?.ts || 0;
|
|
114
125
|
if (now - lastSeen > this.staleTtl) {
|
|
115
126
|
this.users.delete(userId);
|
|
116
127
|
changed = true;
|
|
117
128
|
}
|
|
118
129
|
}
|
|
119
130
|
if (changed) {
|
|
131
|
+
this.cachedUsersList = null;
|
|
120
132
|
this.notifyListeners();
|
|
121
133
|
}
|
|
122
134
|
}, this.pruneInterval);
|
|
@@ -168,7 +180,7 @@ export class Lobby {
|
|
|
168
180
|
* Challenge another user to a game.
|
|
169
181
|
* Returns the ID of the table created for the challenge.
|
|
170
182
|
*/
|
|
171
|
-
async challenge(userId, ruleType,
|
|
183
|
+
async challenge(userId, ruleType, options) {
|
|
172
184
|
const tableId = getUID();
|
|
173
185
|
await this.nchan.publishChallenge({
|
|
174
186
|
type: "offer",
|
|
@@ -177,7 +189,6 @@ export class Lobby {
|
|
|
177
189
|
challengeeId: userId,
|
|
178
190
|
ruleType,
|
|
179
191
|
tableId,
|
|
180
|
-
rematch,
|
|
181
192
|
options,
|
|
182
193
|
});
|
|
183
194
|
return tableId;
|
|
@@ -251,6 +262,7 @@ export class Lobby {
|
|
|
251
262
|
console.error("Error leaving lobby:", e);
|
|
252
263
|
}
|
|
253
264
|
this.users.clear();
|
|
265
|
+
this.cachedUsersList = null;
|
|
254
266
|
this.pendingChallenges = [];
|
|
255
267
|
this.deduplicator.clear();
|
|
256
268
|
this.presenceMessageCount = 0;
|
|
@@ -276,15 +288,33 @@ export class Lobby {
|
|
|
276
288
|
* Handles incoming presence updates.
|
|
277
289
|
* Note: Nchan guarantees ordered delivery, so we don't need to check meta.ts for ordering.
|
|
278
290
|
* The last message received for each userId will be the current state.
|
|
291
|
+
*
|
|
292
|
+
* We deduplicate notifications here because the Lobby has domain knowledge of which
|
|
293
|
+
* fields are "meaningful" (e.g. userName, tableId) vs "noise" (e.g. meta.ts heartbeats).
|
|
279
294
|
*/
|
|
280
295
|
handlePresenceUpdate(msg) {
|
|
296
|
+
const existing = this.users.get(msg.userId);
|
|
281
297
|
if (msg.type === "leave") {
|
|
282
|
-
|
|
298
|
+
if (existing) {
|
|
299
|
+
this.users.delete(msg.userId);
|
|
300
|
+
this.cachedUsersList = null;
|
|
301
|
+
this.notifyListeners();
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
else if (msg.type === "join") {
|
|
305
|
+
this.users.set(msg.userId, msg);
|
|
306
|
+
this.cachedUsersList = null;
|
|
307
|
+
this.notifyListeners();
|
|
283
308
|
}
|
|
284
309
|
else {
|
|
310
|
+
// Heartbeat or other update
|
|
311
|
+
const changed = !existing || this.hasMeaningfulChange(existing, msg);
|
|
285
312
|
this.users.set(msg.userId, msg);
|
|
313
|
+
if (changed) {
|
|
314
|
+
this.cachedUsersList = null;
|
|
315
|
+
this.notifyListeners();
|
|
316
|
+
}
|
|
286
317
|
}
|
|
287
|
-
this.notifyListeners();
|
|
288
318
|
}
|
|
289
319
|
handleChallenge(msg) {
|
|
290
320
|
// Deduplicator tracks state from ALL challenge interactions (offer, accept, decline, cancel)
|
|
@@ -300,7 +330,18 @@ export class Lobby {
|
|
|
300
330
|
this.listeners.forEach((cb) => cb(list));
|
|
301
331
|
}
|
|
302
332
|
getUsersList() {
|
|
303
|
-
|
|
333
|
+
if (this.cachedUsersList) {
|
|
334
|
+
return this.cachedUsersList;
|
|
335
|
+
}
|
|
336
|
+
this.cachedUsersList = Array.from(this.users.values()).sort((a, b) => a.userName.localeCompare(b.userName));
|
|
337
|
+
return this.cachedUsersList;
|
|
338
|
+
}
|
|
339
|
+
hasMeaningfulChange(oldMsg, nextMsg) {
|
|
340
|
+
return (oldMsg.userName !== nextMsg.userName ||
|
|
341
|
+
oldMsg.tableId !== nextMsg.tableId ||
|
|
342
|
+
oldMsg.ruleType !== nextMsg.ruleType ||
|
|
343
|
+
oldMsg.opponentId !== nextMsg.opponentId ||
|
|
344
|
+
JSON.stringify(oldMsg.seek) !== JSON.stringify(nextMsg.seek));
|
|
304
345
|
}
|
|
305
346
|
}
|
|
306
347
|
//# sourceMappingURL=lobby.js.map
|
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,
|
|
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,20 +93,25 @@ 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;
|
|
98
|
-
const
|
|
109
|
+
const initialReconnectDelay = 8000;
|
|
110
|
+
const maxReconnectDelay = 60000;
|
|
99
111
|
let reconnectTimer = null;
|
|
100
112
|
let firstConnection = true;
|
|
113
|
+
const CONNECTION_TIMEOUT_MS = 20000;
|
|
114
|
+
let connectionTimeoutTimer = null;
|
|
101
115
|
const subscription = {
|
|
102
116
|
stop: () => {
|
|
103
117
|
stopped = true;
|
|
@@ -105,6 +119,10 @@ export class NchanClient {
|
|
|
105
119
|
clearTimeout(reconnectTimer);
|
|
106
120
|
reconnectTimer = null;
|
|
107
121
|
}
|
|
122
|
+
if (connectionTimeoutTimer) {
|
|
123
|
+
clearTimeout(connectionTimeoutTimer);
|
|
124
|
+
connectionTimeoutTimer = null;
|
|
125
|
+
}
|
|
108
126
|
if (ws) {
|
|
109
127
|
ws.close();
|
|
110
128
|
ws = null;
|
|
@@ -123,7 +141,16 @@ export class NchanClient {
|
|
|
123
141
|
resolveReady();
|
|
124
142
|
return;
|
|
125
143
|
}
|
|
144
|
+
console.log(`[NchanClient ${ts()}] Connecting to ${url} (attempt ${reconnectAttempts + 1})`);
|
|
126
145
|
ws = new globalThis.WebSocket(url);
|
|
146
|
+
if (connectionTimeoutTimer) {
|
|
147
|
+
clearTimeout(connectionTimeoutTimer);
|
|
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?.();
|
|
127
154
|
ws.onmessage = (event) => {
|
|
128
155
|
onMessage(event.data);
|
|
129
156
|
};
|
|
@@ -131,25 +158,40 @@ export class NchanClient {
|
|
|
131
158
|
const isReconnect = !firstConnection;
|
|
132
159
|
firstConnection = false;
|
|
133
160
|
reconnectAttempts = 0;
|
|
134
|
-
// Clear any pending reconnect timer from previous disconnect
|
|
135
161
|
if (reconnectTimer) {
|
|
136
162
|
clearTimeout(reconnectTimer);
|
|
137
163
|
reconnectTimer = null;
|
|
138
164
|
}
|
|
165
|
+
if (connectionTimeoutTimer) {
|
|
166
|
+
clearTimeout(connectionTimeoutTimer);
|
|
167
|
+
connectionTimeoutTimer = null;
|
|
168
|
+
}
|
|
169
|
+
console.log(`[NchanClient ${ts()}] Connected to ${url}`);
|
|
139
170
|
resolveReady();
|
|
140
171
|
if (isReconnect && subscription.onReconnect) {
|
|
141
172
|
subscription.onReconnect();
|
|
142
173
|
}
|
|
143
174
|
};
|
|
144
|
-
ws.onclose = () => {
|
|
175
|
+
ws.onclose = (event) => {
|
|
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
|
+
}
|
|
145
181
|
if (!stopped) {
|
|
146
|
-
|
|
182
|
+
if (reconnectAttempts >= 10) {
|
|
183
|
+
console.error(`[NchanClient ${ts()}] Max reconnect attempts reached for ${url}, giving up`);
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
const delay = Math.min(Math.pow(2, reconnectAttempts) * initialReconnectDelay, maxReconnectDelay);
|
|
147
187
|
reconnectAttempts++;
|
|
188
|
+
console.log(`[NchanClient ${ts()}] Reconnecting in ${delay}ms (attempt ${reconnectAttempts})`);
|
|
148
189
|
reconnectTimer = setTimeout(connect, delay);
|
|
149
190
|
reconnectTimer.unref?.();
|
|
150
191
|
}
|
|
151
192
|
};
|
|
152
|
-
ws.onerror = () => {
|
|
193
|
+
ws.onerror = (event) => {
|
|
194
|
+
console.error(`[NchanClient ${ts()}] WebSocket error on ${url}:`, event);
|
|
153
195
|
ws?.close();
|
|
154
196
|
};
|
|
155
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
|
@@ -34,21 +34,6 @@ export interface PresenceMessage {
|
|
|
34
34
|
tableId?: string;
|
|
35
35
|
isSpectator?: boolean;
|
|
36
36
|
}
|
|
37
|
-
/**
|
|
38
|
-
* Context about a previous game for rematch challenges.
|
|
39
|
-
*/
|
|
40
|
-
export interface RematchInfo {
|
|
41
|
-
readonly opponentId?: string;
|
|
42
|
-
readonly opponentName?: string;
|
|
43
|
-
readonly ruleType?: string;
|
|
44
|
-
readonly lastScores: {
|
|
45
|
-
readonly userId: string;
|
|
46
|
-
readonly score: number;
|
|
47
|
-
}[];
|
|
48
|
-
readonly isRematch: boolean;
|
|
49
|
-
readonly nextTurnId: string;
|
|
50
|
-
readonly options?: Record<string, string>;
|
|
51
|
-
}
|
|
52
37
|
/**
|
|
53
38
|
* Peer-to-peer challenge request
|
|
54
39
|
*/
|
|
@@ -60,7 +45,6 @@ export interface ChallengeMessage {
|
|
|
60
45
|
challengeeId: string;
|
|
61
46
|
ruleType: string;
|
|
62
47
|
tableId?: string;
|
|
63
|
-
readonly rematch?: RematchInfo;
|
|
64
48
|
readonly options?: Record<string, string>;
|
|
65
49
|
meta?: Meta;
|
|
66
50
|
}
|
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":"AAsGA;;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.25.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,13 +51,13 @@
|
|
|
51
51
|
"@playwright/test": "^1.60.0",
|
|
52
52
|
"@types/jest": "30.0.0",
|
|
53
53
|
"@types/ws": "^8.18.1",
|
|
54
|
-
"esbuild": "^0.28.
|
|
54
|
+
"esbuild": "^0.28.1",
|
|
55
55
|
"jest": "^30.4.2",
|
|
56
|
-
"oxlint": "^1.
|
|
57
|
-
"testcontainers": "^
|
|
58
|
-
"ts-jest": "^29.4.
|
|
56
|
+
"oxlint": "^1.68.0",
|
|
57
|
+
"testcontainers": "^12.0.1",
|
|
58
|
+
"ts-jest": "^29.4.11",
|
|
59
59
|
"typescript": "^6.0.3",
|
|
60
|
-
"ws": "^8.
|
|
60
|
+
"ws": "^8.21.0"
|
|
61
61
|
},
|
|
62
62
|
"browserslist": [
|
|
63
63
|
"defaults",
|