@emeryld/rrroutes-client 2.8.9 → 2.8.10
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/index.cjs +131 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +131 -6
- package/dist/index.mjs.map +1 -1
- package/dist/sockets/socket.client.core.d.ts +40 -0
- package/dist/sockets/socket.client.debug.d.ts +2 -2
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -1924,7 +1924,9 @@ var SocketClient = class {
|
|
|
1924
1924
|
this.hbTimer = null;
|
|
1925
1925
|
// stats
|
|
1926
1926
|
this.roomCounts = /* @__PURE__ */ new Map();
|
|
1927
|
+
this.roomJoinMeta = /* @__PURE__ */ new Map();
|
|
1927
1928
|
this.handlerMap = /* @__PURE__ */ new Map();
|
|
1929
|
+
this.hasConnected = false;
|
|
1928
1930
|
this.events = events;
|
|
1929
1931
|
this.socket = opts.socket ?? null;
|
|
1930
1932
|
this.environment = opts.environment ?? "development";
|
|
@@ -1933,11 +1935,14 @@ var SocketClient = class {
|
|
|
1933
1935
|
this.sysEvents = opts.sys;
|
|
1934
1936
|
this.roomJoinSchema = buildRoomPayloadSchema(this.config.joinMetaMessage);
|
|
1935
1937
|
this.roomLeaveSchema = buildRoomPayloadSchema(this.config.leaveMetaMessage);
|
|
1938
|
+
this.reconnection = this.resolveReconnectionOptions(opts.reconnection);
|
|
1939
|
+
this.hasConnected = Boolean(this.socket?.connected);
|
|
1936
1940
|
const hb = opts.heartbeat ?? {};
|
|
1937
1941
|
this.hb = {
|
|
1938
1942
|
intervalMs: hb.intervalMs ?? 15e3,
|
|
1939
1943
|
timeoutMs: hb.timeoutMs ?? 7500
|
|
1940
1944
|
};
|
|
1945
|
+
this.configureReconnection();
|
|
1941
1946
|
if (!this.socket) {
|
|
1942
1947
|
this.dbg({
|
|
1943
1948
|
type: "lifecycle",
|
|
@@ -1964,6 +1969,8 @@ var SocketClient = class {
|
|
|
1964
1969
|
return;
|
|
1965
1970
|
}
|
|
1966
1971
|
const socket = this.socket;
|
|
1972
|
+
const isReconnect = this.hasConnected;
|
|
1973
|
+
this.hasConnected = true;
|
|
1967
1974
|
this.dbg({
|
|
1968
1975
|
type: "connection",
|
|
1969
1976
|
phase: "connect_event",
|
|
@@ -1973,12 +1980,15 @@ var SocketClient = class {
|
|
|
1973
1980
|
}
|
|
1974
1981
|
});
|
|
1975
1982
|
this.logSocketConfigSnapshot("connect_event");
|
|
1976
|
-
void
|
|
1977
|
-
this.
|
|
1983
|
+
void (async () => {
|
|
1984
|
+
if (isReconnect && this.reconnection.restoreRooms) {
|
|
1985
|
+
await this.restoreRooms();
|
|
1986
|
+
}
|
|
1987
|
+
await this.getSysEvent("sys:connect")({
|
|
1978
1988
|
socket,
|
|
1979
1989
|
client: this
|
|
1980
|
-
})
|
|
1981
|
-
).catch((error) => {
|
|
1990
|
+
});
|
|
1991
|
+
})().catch((error) => {
|
|
1982
1992
|
this.dbg({
|
|
1983
1993
|
type: "connection",
|
|
1984
1994
|
phase: "connect_event",
|
|
@@ -2150,7 +2160,7 @@ var SocketClient = class {
|
|
|
2150
2160
|
};
|
|
2151
2161
|
if (this.socket) {
|
|
2152
2162
|
this.socket.on("connect", this.onConnect);
|
|
2153
|
-
this.socket.on("reconnect", this.onReconnect);
|
|
2163
|
+
this.socket.io.on("reconnect", this.onReconnect);
|
|
2154
2164
|
this.socket.on("disconnect", this.onDisconnect);
|
|
2155
2165
|
this.socket.on("connect_error", this.onConnectError);
|
|
2156
2166
|
this.socket.on("sys:pong", this.onPong);
|
|
@@ -2223,6 +2233,57 @@ var SocketClient = class {
|
|
|
2223
2233
|
getSysEvent(name) {
|
|
2224
2234
|
return this.sysEvents[name];
|
|
2225
2235
|
}
|
|
2236
|
+
resolveReconnectionOptions(value) {
|
|
2237
|
+
if (value === true) {
|
|
2238
|
+
return { mode: "managed", restoreRooms: true };
|
|
2239
|
+
}
|
|
2240
|
+
if (value === false) {
|
|
2241
|
+
return { mode: "manual", restoreRooms: true };
|
|
2242
|
+
}
|
|
2243
|
+
return {
|
|
2244
|
+
...value,
|
|
2245
|
+
mode: value?.mode ?? "inherit",
|
|
2246
|
+
restoreRooms: value?.restoreRooms ?? true
|
|
2247
|
+
};
|
|
2248
|
+
}
|
|
2249
|
+
configureReconnection() {
|
|
2250
|
+
if (!this.socket) return;
|
|
2251
|
+
const manager = this.socket.io;
|
|
2252
|
+
const options = this.reconnection;
|
|
2253
|
+
if (options.mode === "managed") {
|
|
2254
|
+
manager.reconnection(true);
|
|
2255
|
+
if (options.attempts !== void 0) {
|
|
2256
|
+
manager.reconnectionAttempts(options.attempts);
|
|
2257
|
+
}
|
|
2258
|
+
if (options.delayMs !== void 0) {
|
|
2259
|
+
manager.reconnectionDelay(options.delayMs);
|
|
2260
|
+
}
|
|
2261
|
+
if (options.delayMaxMs !== void 0) {
|
|
2262
|
+
manager.reconnectionDelayMax(options.delayMaxMs);
|
|
2263
|
+
}
|
|
2264
|
+
if (options.randomizationFactor !== void 0) {
|
|
2265
|
+
manager.randomizationFactor(options.randomizationFactor);
|
|
2266
|
+
}
|
|
2267
|
+
if (options.timeoutMs !== void 0) {
|
|
2268
|
+
manager.timeout(options.timeoutMs);
|
|
2269
|
+
}
|
|
2270
|
+
} else if (options.mode === "manual") {
|
|
2271
|
+
manager.reconnection(false);
|
|
2272
|
+
}
|
|
2273
|
+
this.dbg({
|
|
2274
|
+
type: "connection",
|
|
2275
|
+
phase: "reconnect_config",
|
|
2276
|
+
details: {
|
|
2277
|
+
mode: options.mode,
|
|
2278
|
+
restoreRooms: options.restoreRooms,
|
|
2279
|
+
attempts: options.attempts,
|
|
2280
|
+
delayMs: options.delayMs,
|
|
2281
|
+
delayMaxMs: options.delayMaxMs,
|
|
2282
|
+
randomizationFactor: options.randomizationFactor,
|
|
2283
|
+
timeoutMs: options.timeoutMs
|
|
2284
|
+
}
|
|
2285
|
+
});
|
|
2286
|
+
}
|
|
2226
2287
|
dbg(e) {
|
|
2227
2288
|
const d = this.debug;
|
|
2228
2289
|
if (!d.logger) return;
|
|
@@ -2254,6 +2315,63 @@ var SocketClient = class {
|
|
|
2254
2315
|
handlers
|
|
2255
2316
|
};
|
|
2256
2317
|
}
|
|
2318
|
+
/**
|
|
2319
|
+
* Re-emit joins for all rooms with active references without incrementing
|
|
2320
|
+
* their reference counts. This is safe to call after any externally or
|
|
2321
|
+
* internally managed reconnect.
|
|
2322
|
+
*/
|
|
2323
|
+
async restoreRooms() {
|
|
2324
|
+
if (!this.socket?.connected) {
|
|
2325
|
+
this.dbg({
|
|
2326
|
+
type: "room",
|
|
2327
|
+
phase: "restore",
|
|
2328
|
+
rooms: [],
|
|
2329
|
+
err: "Socket is not connected"
|
|
2330
|
+
});
|
|
2331
|
+
return [];
|
|
2332
|
+
}
|
|
2333
|
+
const restored = [];
|
|
2334
|
+
const desiredRooms = Array.from(this.roomCounts.entries()).filter(([, count]) => count > 0).map(([room]) => room);
|
|
2335
|
+
for (const room of desiredRooms) {
|
|
2336
|
+
const meta = this.roomJoinMeta.get(room);
|
|
2337
|
+
const allowed = await this.getSysEvent("sys:room_join")({
|
|
2338
|
+
rooms: [room],
|
|
2339
|
+
meta,
|
|
2340
|
+
socket: this.socket,
|
|
2341
|
+
client: this
|
|
2342
|
+
});
|
|
2343
|
+
if (!allowed) {
|
|
2344
|
+
this.dbg({
|
|
2345
|
+
type: "room",
|
|
2346
|
+
phase: "restore",
|
|
2347
|
+
rooms: [room],
|
|
2348
|
+
err: "sys:room_join handler aborted restore"
|
|
2349
|
+
});
|
|
2350
|
+
continue;
|
|
2351
|
+
}
|
|
2352
|
+
const payloadResult = this.roomJoinSchema.safeParse({
|
|
2353
|
+
rooms: [room],
|
|
2354
|
+
meta
|
|
2355
|
+
});
|
|
2356
|
+
if (!payloadResult.success) {
|
|
2357
|
+
this.dbg({
|
|
2358
|
+
type: "room",
|
|
2359
|
+
phase: "restore",
|
|
2360
|
+
rooms: [room],
|
|
2361
|
+
err: "payload validation failed",
|
|
2362
|
+
details: this.getValidationDetails(payloadResult.error)
|
|
2363
|
+
});
|
|
2364
|
+
continue;
|
|
2365
|
+
}
|
|
2366
|
+
this.socket.emit(
|
|
2367
|
+
"sys:room_join",
|
|
2368
|
+
payloadResult.data
|
|
2369
|
+
);
|
|
2370
|
+
restored.push(room);
|
|
2371
|
+
}
|
|
2372
|
+
this.dbg({ type: "room", phase: "restore", rooms: restored });
|
|
2373
|
+
return restored;
|
|
2374
|
+
}
|
|
2257
2375
|
toArray(rooms) {
|
|
2258
2376
|
return rooms == null ? [] : Array.isArray(rooms) ? rooms : [rooms];
|
|
2259
2377
|
}
|
|
@@ -2441,6 +2559,9 @@ var SocketClient = class {
|
|
|
2441
2559
|
}
|
|
2442
2560
|
const payload = payloadResult.data;
|
|
2443
2561
|
const normalizedRooms = this.toArray(payload.rooms);
|
|
2562
|
+
for (const room of normalizedRooms) {
|
|
2563
|
+
this.roomJoinMeta.set(room, meta);
|
|
2564
|
+
}
|
|
2444
2565
|
this.socket.emit("sys:room_join", payload);
|
|
2445
2566
|
this.dbg({ type: "room", phase: "join", rooms: normalizedRooms });
|
|
2446
2567
|
}
|
|
@@ -2499,6 +2620,9 @@ var SocketClient = class {
|
|
|
2499
2620
|
}
|
|
2500
2621
|
const payload = payloadResult.data;
|
|
2501
2622
|
const normalizedRooms = this.toArray(payload.rooms);
|
|
2623
|
+
for (const room of normalizedRooms) {
|
|
2624
|
+
this.roomJoinMeta.delete(room);
|
|
2625
|
+
}
|
|
2502
2626
|
this.socket.emit("sys:room_leave", payload);
|
|
2503
2627
|
this.dbg({ type: "room", phase: "leave", rooms: normalizedRooms });
|
|
2504
2628
|
}
|
|
@@ -2641,7 +2765,7 @@ var SocketClient = class {
|
|
|
2641
2765
|
this.stopHeartbeat("destroy");
|
|
2642
2766
|
if (socket) {
|
|
2643
2767
|
socket.off("connect", this.onConnect);
|
|
2644
|
-
socket.off("reconnect", this.onReconnect);
|
|
2768
|
+
socket.io.off("reconnect", this.onReconnect);
|
|
2645
2769
|
socket.off("disconnect", this.onDisconnect);
|
|
2646
2770
|
socket.off("connect_error", this.onConnectError);
|
|
2647
2771
|
socket.off("sys:pong", this.onPong);
|
|
@@ -2658,6 +2782,7 @@ var SocketClient = class {
|
|
|
2658
2782
|
await this.leaveRooms(toLeave, leaveMeta);
|
|
2659
2783
|
}
|
|
2660
2784
|
this.roomCounts.clear();
|
|
2785
|
+
this.roomJoinMeta.clear();
|
|
2661
2786
|
this.dbg({
|
|
2662
2787
|
type: "lifecycle",
|
|
2663
2788
|
phase: "destroy_complete",
|