Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

@bytesocket/server

Package Overview
Dependencies
Maintainers
1
Versions
3
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@bytesocket/server - npm Package Compare versions

Comparing version
0.3.1
to
0.4.0
+752
dist/byte-socket-server-base-3oCYTtHD.d.ts
import { AnyCallback, ByteSocketBase, ErrorContext, EventsForRooms, IByteSocketBase, LifecycleMessage, LifecycleTypes, MsgpackrOptions, SocketEvents, StringKeys, StringNumberKeys, UserMessage } from "@bytesocket/core";
import { UUID } from "node:crypto";
//#region src/types.d.ts
/** The data types actually received from outside.*/
type ServerIncomingData = Buffer | ArrayBuffer | Uint8Array;
/** The data types actually accepted by the server `server.send()` or `ws.send()` methods.*/
type ServerOutgoingData = string | ServerIncomingData;
/**
* Callback used by the authentication function to return the authentication result.
* @param payload - The authenticated user data to attach to the socket.
* @param error - Optional error if authentication failed.
*/
type AuthCallback = (payload: any, error?: Error) => void;
/**
* Authentication function signature. Called when a client sends an auth message.
*
* @typeParam SD - The socket data type (must extend `SocketData`).
* @typeParam D - The type of the authentication data sent by the client.
*
* @example
* const auth: AuthFunction = (socket, data, callback) => {
* if (data.token === "secret") {
* callback({ userId: 1 });
* } else {
* callback(null, new Error("Invalid token"));
* }
* };
*/
type AuthFunction<TEvents extends SocketEvents, SD extends SocketData, D = any> = (socket: ISocket<TEvents, SD>, data: D, callback: AuthCallback) => void;
/**
* Callback for global event listeners.
*
* @typeParam SD - The socket data type.
* @typeParam D - The type of the event data.
*
* @example
* socket.on("userJoined", (socket, data) => {
* console.log(`User ${data.userId} joined`);
* });
*/
type EventCallback<TEvents extends SocketEvents, SD extends SocketData, D> = (socket: ISocket<TEvents, SD>, data: D) => void;
/**
* Middleware function for room-scoped events. Can inspect or block the broadcast.
*
* @typeParam SD - The socket data type.
* @typeParam D - The type of the event data.
*
* @example
* io.rooms.on("chat", "message", (socket, data, next) => {
* if (data.text.includes("badword")) {
* next(new Error("Profanity not allowed"));
* } else {
* next();
* }
* });
*
* // Also supports async functions / Promises
* io.rooms.on("chat", "message", async (socket, data, next) => {
* const isValid = await validateMessage(data);
* if (!isValid) {
* return next(new Error("Invalid"));
* }
* next();
* });
*/
type RoomEventMiddleware<TEvents extends SocketEvents, SD extends SocketData, D> = (socket: ISocket<TEvents, SD>, data: D, next: MiddlewareNext) => void | Promise<void>;
/** Next function for middleware chains. Call `next()` to proceed, or `next(error)` to abort. */
type MiddlewareNext = (error?: unknown | null) => void;
/**
* Global middleware function. Runs before any user message is processed.
*
* @typeParam SD - The socket data type.
*
* @example
* io.use((socket, ctx, next) => {
* console.log("Received:", ctx);
* next();
* });
*/
type Middleware<TEvents extends SocketEvents = SocketEvents, SD extends SocketData = SocketData> = (socket: ISocket<TEvents, SD>, ctx: UserMessage, next: MiddlewareNext) => void | Promise<void>;
/**
* Data automatically attached to every socket by the server.
* Contains HTTP request information available during the WebSocket upgrade.
*/
type SocketData = {
/** Unique identifier for the socket (UUID v4). */socketKey: UUID; /** The url string from the upgrade request. */
url: string; /** The query string from the upgrade request. */
query: string; /** The `Host` header value. */
host: string; /** The `Cookie` header value. */
cookie: string; /** The `User-Agent` header value. */
userAgent: string; /** The `Authorization` header value. */
authorization: string; /** The `X-Forwarded-For` header value. */
xForwardedFor: string;
};
/**
* Configuration options for the ByteSocket server.
*
* @typeParam TEvents - The socket events definition.
* @typeParam SD - The socket data type (must extend `SocketData`).
*
* @example
* const io = new ByteSocket({
* debug: true,
* authTimeout: 10000,
* origins: ["https://example.com"],
* serialization: "binary",
* auth: (socket, data, callback) => {
* // validate token
* callback({ userId: 1 });
* }
* });
*/
type ByteSocketOptionsBase<TEvents extends SocketEvents = SocketEvents, SD extends SocketData = SocketData> = {
/** Enable debug logging to console. @default false */debug?: boolean; /** Timeout in milliseconds for global middleware execution. @default 5000 */
middlewareTimeout?: number; /** Timeout in milliseconds for room event middleware execution. @default 5000 */
roomMiddlewareTimeout?: number; /** Timeout for authentication response in milliseconds. @default 5000 */
authTimeout?: number; /** List of allowed origins for CORS. If empty, all origins are allowed. */
origins?: string[]; /** Serialization format: `"json"` or `"binary"` (msgpack). @default "binary" */
serialization?: "json" | "binary"; /** Room name used for global broadcasts. @default "__bytesocket_broadcast__" */
broadcastRoom?: string; /** Options passed directly to the underlying msgpackr Packr instance. */
msgpackrOptions?: MsgpackrOptions; /** Action to take when a global middleware error occurs. @default "ignore" */
onMiddlewareError?: "ignore" | "close" | ((error: unknown, socket: ISocket<TEvents, SD>) => void); /** Action to take when a global middleware times out. @default "ignore" */
onMiddlewareTimeout?: "ignore" | "close" | ((error: unknown, socket: ISocket<TEvents, SD>) => void); /** Authentication configuration. */
auth?: AuthFunction<TEvents, SD>;
/**
* Maximum milliseconds of inactivity (no messages received or pongs) before the connection is closed.
* Set to `0` to disable.
* @default 120000
*/
idleTimeout?: number;
/**
* Whether the server should automatically send WebSocket ping frames to keep
* the connection alive and detect dead clients.
* @default true
*/
sendPingsAutomatically?: boolean;
};
//#endregion
//#region src/interfaces.d.ts
/** Bulk operations for multiple rooms. */
interface ISocketRoomsBulk<TEvents extends SocketEvents> {
/**
* Events that can be emitted to multiple rooms at once.
*
* **Recommended pattern:** Use a union of `{ rooms: R; event: T }` objects:
*
* @example
* interface MyEvents extends SocketEvents {
* emitRooms:
* | { rooms: ['room1', 'room2']; event: { 'alert': { msg: string } } }
* | { rooms: ['roomA', 'roomB']; event: { 'message': { text: string } } };
*
* socket.rooms.bulk.emit(["room1", "room2"], "alert", { msg: "Hello" });
* }
*/
emit: <Rs extends NonNullable<TEvents["emitRooms"]>["rooms"], E extends StringNumberKeys<EventsForRooms<NonNullable<TEvents["emitRooms"]>, Rs>>, D extends NonNullable<EventsForRooms<NonNullable<TEvents["emitRooms"]>, Rs>>[E]>(rooms: Rs, event: E, data: D) => this;
/**
* Join multiple rooms.
* @example socket.rooms.bulk.join(["lobby", "notifications"]);
*/
join: (rooms: string[]) => this;
/**
* Leave multiple rooms.
* @example socket.rooms.bulk.leave(["lobby", "notifications"]);
*/
leave: (rooms: string[]) => this;
}
/**
* Room API available on individual socket instances (client-side or server-side socket).
* Provides methods to join/leave rooms and emit to rooms.
*
* @typeParam TEvents - The socket events definition.
*/
interface ISocketRooms<TEvents extends SocketEvents> {
/**
* Publishes a raw message to a specific room without applying any serialization or encoding.
*
* This method is useful for sending custom protocol messages or pre-encoded data directly
* to all sockets subscribed to the given room. It bypasses the built-in serialization layer,
* so you are responsible for ensuring that the message format matches what the clients expect.
*
* If the socket has been closed, this method does nothing.
*
* @param room - The name of the room to publish the message to.
* @param message - The raw message to send. Can be a `string` (UTF-8 text) or an `ArrayBuffer` / `Buffer` (binary data).
* @param isBinary - Optional. If `true`, the message is sent as a binary WebSocket frame.
* If `false` or omitted, the frame type is inferred from the type of `message`
* (`string` → text frame, `ArrayBuffer`/`Buffer` → binary frame).
* @param compress - Optional. If `true`, the message will be compressed using the WebSocket
* permessage-deflate extension (if negotiated with the client).
*
* @example
* // Send a JSON string to all sockets in the "lobby" room
* socket.rooms.publishRaw("lobby", JSON.stringify({ type: "announcement", text: "Hello!" }));
*
* @example
* // Send pre-encoded binary data (e.g., MessagePack) to the "game" room
* const packedData = msgpack.encode({ event: "move", x: 10, y: 20 });
* socket.rooms.publishRaw("game", packedData, true);
*/
publishRaw: (room: string, message: ServerOutgoingData, isBinary?: boolean, compress?: boolean) => this;
/**
* Emit a typed event to a specific room (server-side publish).
*
* @typeParam R - Room name (must be a key in `TEvents['emitRoom']`).
* @typeParam E - Event name.
* @typeParam D - Event data type.
* @param room - The target room.
* @param event - The event name.
* @param data - The event payload.
* @returns This server instance (for chaining).
*
* @example socket.rooms.emit("chat", "message", { text: "Hi" });
*/
emit: <R extends StringKeys<TEvents["emitRoom"]>, E extends StringNumberKeys<NonNullable<TEvents["emitRoom"]>[R]>, D extends NonNullable<TEvents["emitRoom"]>[R][E]>(room: R, event: E, data: D) => this;
/**
* Join a single room.
* @example socket.rooms.join("lobby");
*/
join: (room: string) => this;
/**
* Leave a single room.
* @example socket.rooms.leave("lobby");
*/
leave: (room: string) => this;
/**
* Get a list of rooms this socket is currently subscribed to.
* By default, the internal broadcast room is excluded.
*
* @param includeBroadcast - If `true`, includes the broadcast room in the result.
* @returns Array of room names.
*
* @example
* socket.rooms.list(); // ['chat', 'lobby']
* socket.rooms.list(true); // ['chat', 'lobby', '__bytesocket_broadcast__']
*/
list: (includeBroadcast?: boolean) => string[];
/** Bulk operations for multiple rooms. */
bulk: ISocketRoomsBulk<TEvents>;
}
/**
* Public API of an individual WebSocket connection.
*
* @typeParam TEvents - Event map type.
* @typeParam SD - Socket data type (extends `SocketData`).
*/
interface ISocket<TEvents extends SocketEvents = SocketEvents, SD extends SocketData = SocketData> {
/**
* Room management and room-scoped event emission.
*
* @example
* socket.rooms.join("chat");
* socket.rooms.emit("chat", "message", { text: "Hello!" });
* console.log(socket.rooms.list()); // ["chat"]
*/
readonly rooms: ISocketRooms<TEvents>;
/** Unique identifier for the socket (same as `userData.socketKey`). */
readonly id: string;
/**
* Payload attached during successful authentication.
* Available in middleware and event listeners.
*
* @example
* io.on("chat", (socket, data) => {
* console.log(`Message from ${socket.payload.username}`);
* });
*/
payload: any;
/**
* Mutable object for storing arbitrary data during the socket's lifetime.
* Useful for passing data between middleware and event handlers.
*
* @example
* io.use((socket, ctx, next) => {
* socket.locals.requestId = randomUUID();
* next();
* });
*/
locals: any;
/**
* Whether the socket has completed authentication (or auth is disabled).
* Returns `true` if no auth is configured, or if authentication succeeded.
*/
readonly isAuthenticated: boolean;
/** Whether the socket has been closed. */
readonly isClosed: boolean;
/**
* Whether the socket is currently able to send messages.
* Returns `true` if the WebSocket is open and authentication (if configured) has succeeded.
* Useful for checking readiness before calling `sendRaw()` or `rooms.publishRaw()`.
* No need to use it with `emit()` or `send()` because they already use it under the hood.
*
* @example
* if (socket.canSend) {
* socket.sendRaw('PROTOCOL: custom-v1');
* }
*/
readonly canSend: boolean;
/**
* The user data object attached during the WebSocket upgrade.
* Contains HTTP request headers and other metadata.
*
* @example
* console.log(socket.userData.socketKey);
*/
readonly userData: SD;
/**
* The path component of the URL requested by the client during the
* WebSocket upgrade.
*
* @example
* // If the client connected to `wss://example.com/socket?room=lobby`,
* // this will be `"/socket"`.
*/
readonly url: string;
/**
* The raw query string from the WebSocket upgrade request.
*
* @example
* // If the client connected to `wss://example.com/socket?room=lobby&token=abc`,
* // this will be `"room=lobby&token=abc"`.
* const query = socket.query;
* const params = new URLSearchParams(socket.query);
* console.log(params.get('room')); // "lobby"
*/
readonly query: string;
/**
* The `Cookie` header from the WebSocket upgrade request.
*
* @example
* // Useful for session handling when not using the Authorization header.
* const cookies = socket.cookie;
* const sessionId = parseCookies(cookies)?.sessionId;
*/
readonly cookie: string;
/**
* The `Authorization` header from the WebSocket upgrade request.
* Typically contains a Bearer token or Basic auth credentials.
*
* @example
* const authHeader = socket.authorization;
* if (authHeader?.startsWith('Bearer ')) {
* const token = authHeader.slice(7);
* // validate token...
* }
*/
readonly authorization: string;
/**
* The `User-Agent` header from the WebSocket upgrade request.
*
* @example
* console.log(`Client: ${socket.userAgent}`);
* // "Client: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ..."
*/
readonly userAgent: string;
/**
* The `Host` header from the WebSocket upgrade request.
* Includes the domain and (optionally) port the client used to connect.
*
* @example
* console.log(socket.host); // "api.example.com"
*/
readonly host: string;
/**
* The `X-Forwarded-For` header from the WebSocket upgrade request.
* Contains the originating client IP when behind a proxy or load balancer.
*
* @example
* const clientIp = socket.xForwardedFor?.split(',')[0].trim() || 'unknown';
* console.log(`Client IP: ${clientIp}`);
*/
readonly xForwardedFor: string;
/**
* Emit a typed global event to this socket only.
*
* @typeParam E - Event name (must be a key in `TEvents['emit']`).
* @typeParam D - Event data type.
* @param event - The event name.
* @param data - The event payload.
* @returns This socket instance (for chaining).
*
* @example
* socket.emit("privateMessage", { from: "server", text: "Hello" });
*/
emit<E extends StringNumberKeys<TEvents["emit"]>, D extends NonNullable<TEvents["emit"]>[E]>(event: E, data: D): this;
/**
* Send a raw message (string or binary) directly to this socket.
* Bypasses serialization. Useful for custom protocols.
*
* @param message - The message to send.
* @param isBinary - Whether to send as binary frame.
* @default true `if message is not a string`.
* @param compress - Whether to use permessage-deflate compression.
* @returns This socket instance.
*
* @example
* socket.sendRaw(JSON.stringify({ custom: "data" }));
*/
sendRaw(message: ServerOutgoingData, isBinary?: boolean, compress?: boolean): this;
/**
* Send any lifecycle or user message to this socket.
* Automatically encodes according to the configured serialization.
* You typically use `emit()` or `broadcast()` instead.
*
* @param payload - The message to send (user message or lifecycle message).
* @returns This socket instance.
*
* @example
* socket.send({ event: "echo", data: { message: "hello" } });
*/
send<R extends string, E extends string | number, D>(payload: LifecycleMessage<R, D> | UserMessage<R, E, D>): this;
/**
* Broadcast a global event to all **other** connected sockets.
* The publishing socket does **not** receive the message.
*
* @typeParam E - Event name.
* @typeParam D - Event data type.
* @param event - The event name.
* @param data - The event payload.
* @returns This socket instance.
*
* @example
* socket.broadcast("userJoined", { userId: socket.id });
*/
broadcast<E extends StringNumberKeys<TEvents["emit"]>, D extends NonNullable<TEvents["emit"]>[E]>(event: E, data: D): this;
/**
* Close the WebSocket connection gracefully.
*
* @param code - WebSocket close code. @default 1000
* @param reason - Close reason string. @default "normal"
*
* @example
* socket.close(1008, "Policy violation");
*/
close(code?: number, reason?: string): void;
/**
* Handle an incoming auth message. Sets up timeout, calls user-provided auth function,
* and manages the success/failure lifecycle.
*
* @internal
*/
_handleAuth<D>(parsed: {
type: LifecycleTypes.auth;
data: D;
} | null, auth: AuthFunction<TEvents, SD, D> | undefined, authTimeout: number, next: MiddlewareNext): void;
}
/**
* Lifecycle event API available on the ByteSocket server instance.
* Allows listening to connection, authentication, message, close, and error events.
*
* @typeParam TEvents - The socket events definition.
* @typeParam SD - The socket data type.
*/
interface ILifecycleServer<TEvents extends SocketEvents, SD extends SocketData, UpgradeCallback extends AnyCallback> {
/** Register a listener for the HTTP upgrade phase. */
onUpgrade: (callback: UpgradeCallback) => this;
/** Remove a listener for the HTTP upgrade phase. */
offUpgrade: (callback?: UpgradeCallback) => this;
/** Register a one-time listener for the HTTP upgrade phase. */
onceUpgrade: (callback: UpgradeCallback) => this;
/** Register a listener for socket open (after successful auth). */
onOpen: (callback: (socket: ISocket<TEvents, SD>) => void) => this;
/** Remove a listener for socket open. */
offOpen: (callback?: (socket: ISocket<TEvents, SD>) => void) => this;
/** Register a one-time listener for socket open. */
onceOpen: (callback: (socket: ISocket<TEvents, SD>) => void) => this;
/** Register a listener for authentication success. */
onAuthSuccess: (callback: (socket: ISocket<TEvents, SD>) => void) => this;
/** Remove a listener for authentication success. */
offAuthSuccess: (callback?: (socket: ISocket<TEvents, SD>) => void) => this;
/** Register a one-time listener for authentication success. */
onceAuthSuccess: (callback: (socket: ISocket<TEvents, SD>) => void) => this;
/** Register a listener for authentication failure. */
onAuthError: (callback: (socket: ISocket<TEvents, SD>, ctx: ErrorContext) => void) => this;
/** Remove a listener for authentication failure. */
offAuthError: (callback?: (socket: ISocket<TEvents, SD>, ctx: ErrorContext) => void) => this;
/** Register a one-time listener for authentication failure. */
onceAuthError: (callback: (socket: ISocket<TEvents, SD>, ctx: ErrorContext) => void) => this;
/** Register a listener for raw incoming messages. */
onMessage: (callback: (socket: ISocket<TEvents, SD>, data: ServerIncomingData, isBinary: boolean) => void) => this;
/** Remove a listener for raw incoming messages. */
offMessage: (callback?: (socket: ISocket<TEvents, SD>, data: ServerIncomingData, isBinary: boolean) => void) => this;
/** Register a one-time listener for raw incoming messages. */
onceMessage: (callback: (socket: ISocket<TEvents, SD>, data: ServerIncomingData, isBinary: boolean) => void) => this;
/** Register a listener for socket close. */
onClose: (callback: (socket: ISocket<TEvents, SD>, code: number, reason: ServerIncomingData) => void) => this;
/** Remove a listener for socket close. */
offClose: (callback?: (socket: ISocket<TEvents, SD>, code: number, reason: ServerIncomingData) => void) => this;
/** Register a one-time listener for socket close. */
onceClose: (callback: (socket: ISocket<TEvents, SD>, code: number, reason: ServerIncomingData) => void) => this;
/** Register a listener for errors. */
onError: (callback: (socket: ISocket<TEvents, SD> | null, ctx: ErrorContext) => void) => this;
/** Remove a listener for errors. */
offError: (callback?: (socket: ISocket<TEvents, SD> | null, ctx: ErrorContext) => void) => this;
/** Register a one-time listener for errors. */
onceError: (callback: (socket: ISocket<TEvents, SD> | null, ctx: ErrorContext) => void) => this;
}
/** Lifecycle hooks for room join/leave (single rooms). */
interface IRoomsLifecycleServer<TEvents extends SocketEvents, SD extends SocketData> {
/**
* Register a guard for single room join requests.
* Call `next()` to allow, `next(error)` to reject.
*
* @example
* io.rooms.lifecycle.onJoin((socket, room, next) => {
* if (room === 'admin' && !socket.payload?.isAdmin) {
* next(new Error('Not authorized'));
* } else {
* next();
* }
* });
*/
onJoin: (callback: (socket: ISocket<TEvents, SD>, room: string, next: MiddlewareNext) => void) => this;
/** Remove a guard for single room join requests. */
offJoin: (callback?: (socket: ISocket<TEvents, SD>, room: string, next: MiddlewareNext) => void) => this;
/** Register a one-time guard for single room join requests. */
onceJoin: (callback: (socket: ISocket<TEvents, SD>, room: string, next: MiddlewareNext) => void) => this;
/** Register a guard for single room leave requests. */
onLeave: (callback: (socket: ISocket<TEvents, SD>, room: string, next: MiddlewareNext) => void) => this;
/** Remove a guard for single room leave requests. */
offLeave: (callback?: (socket: ISocket<TEvents, SD>, room: string, next: MiddlewareNext) => void) => this;
/** Register a one-time guard for single room leave requests. */
onceLeave: (callback: (socket: ISocket<TEvents, SD>, room: string, next: MiddlewareNext) => void) => this;
}
/** Lifecycle hooks for bulk room operations. */
interface IRoomsBulkLifecycleServer<TEvents extends SocketEvents, SD extends SocketData> {
/** Register a guard for bulk room join requests. */
onJoin: (callback: (socket: ISocket<TEvents, SD>, rooms: string[], next: MiddlewareNext) => void) => this;
/** Remove a guard for bulk room join requests. */
offJoin: (callback?: (socket: ISocket<TEvents, SD>, rooms: string[], next: MiddlewareNext) => void) => this;
/** Register a one-time guard for bulk room join requests. */
onceJoin: (callback: (socket: ISocket<TEvents, SD>, rooms: string[], next: MiddlewareNext) => void) => this;
/** Register a guard for bulk room leave requests. */
onLeave: (callback: (socket: ISocket<TEvents, SD>, rooms: string[], next: MiddlewareNext) => void) => this;
/** Remove a guard for bulk room leave requests. */
offLeave: (callback?: (socket: ISocket<TEvents, SD>, rooms: string[], next: MiddlewareNext) => void) => this;
/** Register a one-time guard for bulk room leave requests. */
onceLeave: (callback: (socket: ISocket<TEvents, SD>, rooms: string[], next: MiddlewareNext) => void) => this;
}
interface IRoomsBulkServer<TEvents extends SocketEvents, SD extends SocketData> {
/**
* Emit a typed event to multiple rooms at once.
*
* @typeParam Rs - The array of room names.
* @typeParam E - Event name.
* @typeParam D - Event data type.
*
* @example
* interface MyEvents extends SocketEvents {
* emitRooms:
* | { rooms: ['room1', 'room2']; event: { 'alert': { msg: string } } }
* | { rooms: ['roomA', 'roomB']; event: { 'message': { text: string } } };
*
* io.rooms.bulk.emit(['room1', 'room2'], 'alert', { msg: 'Hello both!' });
*/
emit: <Rs extends NonNullable<TEvents["emitRooms"]>["rooms"], E extends StringNumberKeys<EventsForRooms<NonNullable<TEvents["emitRooms"]>, Rs>>, D extends NonNullable<EventsForRooms<NonNullable<TEvents["emitRooms"]>, Rs>>[E]>(rooms: Rs, event: E, data: D) => this;
/** Lifecycle hooks for bulk room operations. */
lifecycle: IRoomsBulkLifecycleServer<TEvents, SD>;
}
/**
* Room management API available on the ByteSocket server instance.
* Provides methods to emit to rooms, publish raw data, and attach room-level middleware.
*
* @typeParam TEvents - The socket events definition.
* @typeParam SD - The socket data type.
*/
interface IRoomsServer<TEvents extends SocketEvents, SD extends SocketData> {
/**
* Publishes a raw message to all sockets subscribed to the given room.
*
* This method broadcasts the data directly to all connected sockets in the room
* using the underlying `ws` server, **without** applying any encoding,
* serialization, or lifecycle processing. It is useful for broadcasting
* custom-formatted messages, pre-encoded payloads, or implementing custom protocols.
*
* If the server instance has been destroyed, this method does nothing.
*
* @param room - The room name to publish the message to. All sockets that have joined this
* room (including the global broadcast room) will receive the message.
* @param message - The raw data to send. Accepts a `string` (sent as a UTF-8 text frame) or
* an `ArrayBuffer` / `Buffer` (sent as a binary frame).
* @param isBinary - Optional. If `true`, forces the message to be sent as a binary WebSocket
* frame. If `false` or omitted, the frame type is inferred from the type of
* `message` (`string` → text, `ArrayBuffer`/`Buffer` → binary).
* @param compress - Optional. If `true`, the message will be compressed using the WebSocket
* permessage-deflate extension (if negotiated with the clients).
*
* @example
* // Broadcast a JSON string to the "lobby" room
* io.rooms.publishRaw("lobby", JSON.stringify({ type: "announcement", text: "Server restart in 5m" }));
*
* @example
* // Broadcast pre-encoded MessagePack data to the "lobby" room
* const packed = msgpack.encode({ event: "system", status: "ok" });
* io.rooms.publishRaw("lobby", packed, true);
*
* @example
* // Send compressed binary data
* const buffer = new Uint8Array([1, 2, 3]);
* io.rooms.publishRaw("updates", buffer, true, true);
*/
publishRaw: (room: string, message: ServerOutgoingData, isBinary?: boolean, compress?: boolean) => this;
/**
* Emit a typed event to a specific room (server-side publish).
*
* @typeParam R - Room name (must be a key in `TEvents['emitRoom']`).
* @typeParam E - Event name.
* @typeParam D - Event data type.
*
* @example
* io.rooms.emit('chat', 'message', { text: 'Hello everyone' });
*/
emit: <R extends StringKeys<TEvents["emitRoom"]>, E extends StringNumberKeys<NonNullable<TEvents["emitRoom"]>[R]>, D extends NonNullable<TEvents["emitRoom"]>[R][E]>(room: R, event: E, data: D) => this;
/** Register a room event middleware. */
on: <R extends StringKeys<TEvents["listenRoom"]>, E extends StringNumberKeys<NonNullable<TEvents["listenRoom"]>[R]>, D extends NonNullable<TEvents["listenRoom"]>[R][E]>(room: R, event: E, callback: RoomEventMiddleware<TEvents, SD, D>) => this;
/** Remove a room event middleware. */
off: <R extends StringKeys<TEvents["listenRoom"]>, E extends StringNumberKeys<NonNullable<TEvents["listenRoom"]>[R]>, D extends NonNullable<TEvents["listenRoom"]>[R][E]>(room: R, event?: E, callback?: RoomEventMiddleware<TEvents, SD, D>) => this;
/** Register a one-time room event middleware. */
once: <R extends StringKeys<TEvents["listenRoom"]>, E extends StringNumberKeys<NonNullable<TEvents["listenRoom"]>[R]>, D extends NonNullable<TEvents["listenRoom"]>[R][E]>(room: R, event: E, callback: RoomEventMiddleware<TEvents, SD, D>) => this;
/** Lifecycle hooks for room join/leave (single rooms). */
lifecycle: IRoomsLifecycleServer<TEvents, SD>;
/** Bulk operations for multiple rooms. */
bulk: IRoomsBulkServer<TEvents, SD>;
}
/**
* Public API of a ByteSocket server instance.
*
* Manages WebSocket connections, rooms, middleware, and event routing.
* The implementation class {@link ByteSocket} should `implement` this interface.
*
* @typeParam TEvents - Event map (extends `SocketEvents`) defining the shape of
* all emit/listen events (global and room‑scoped).
* @typeParam SD - Socket data type that extends `SocketData`.
*/
interface IByteSocket<TEvents extends SocketEvents = SocketEvents, SD extends SocketData = SocketData, UpgradeCallback extends AnyCallback = AnyCallback> extends IByteSocketBase {
/**
* Lifecycle event listeners for connection, authentication, and errors.
*
* @example
* io.lifecycle.onOpen((socket) => console.log('Connected!'));
* io.lifecycle.onAuthError((socket, ctx) => console.error('Auth failed', ctx.error));
* io.lifecycle.onClose((socket, code, msg) => console.log('Closed', code));
*/
readonly lifecycle: ILifecycleServer<TEvents, SD, UpgradeCallback>;
/**
* Room management, room-scoped event emission, and room lifecycle hooks.
*
* @example
* io.rooms.emit('lobby', 'announcement', { text: 'Welcome!' });
* io.rooms.on('chat', 'message', (socket, data, next) => { ... });
* io.rooms.lifecycle.onJoin((socket, room, next) => {
* if (room === 'admin') next(new Error('Not allowed'));
* else next();
* });
*/
readonly rooms: IRoomsServer<TEvents, SD>;
/**
* Map of all currently connected sockets, keyed by socket ID.
*
* **Do not modify this map directly** - it is managed internally.
*
* @example
* for (const [id, socket] of io.sockets) {
* socket.emit('ping', undefined);
* }
*/
readonly sockets: Map<string, ISocket<TEvents, SD>>;
/**
* Indicates whether the server instance has been permanently destroyed.
*
* Once `true`, the instance cannot be reused; all connections have been closed and
* internal resources released. Use {@link destroy} to initiate shutdown.
*
* @example
* if (io.destroyed) {
* console.log('Server is shut down');
* }
*/
readonly destroyed: boolean;
/**
* Emit a global event to all connected sockets.
*
* @typeParam E - Event name (must be a key in `TEvents['emit']`).
* @typeParam D - Event data type.
*
* @example io.emit('userJoined', { userId: '123' });
*/
emit<E extends StringNumberKeys<TEvents["emit"]>, D extends NonNullable<TEvents["emit"]>[E]>(event: E, data: D): this;
/**
* Register a permanent listener for global events.
*
* @typeParam E - Event name (must be a key in `TEvents['listen']`).
*
* @example io.on('userJoined', (socket, data) => { console.log(data.userId); });
*/
on<E extends StringNumberKeys<TEvents["listen"]>, D extends NonNullable<TEvents["listen"]>[E]>(event: E, callback: EventCallback<TEvents, SD, D>): this;
/**
* Remove a listener for global events.
* If no callback is provided, **all** listeners for that event are removed.
*
* @example io.off('userJoined', myCallback);
*/
off<E extends StringNumberKeys<TEvents["listen"]>, D extends NonNullable<TEvents["listen"]>[E]>(event: E, callback?: EventCallback<TEvents, SD, D>): this;
/**
* Register a one-time listener for a global event.
* The callback is removed after the first invocation.
*
* @example io.once('userJoined', (socket, data) => { console.log('First join'); });
*/
once<E extends StringNumberKeys<TEvents["listen"]>, D extends NonNullable<TEvents["listen"]>[E]>(event: E, callback: EventCallback<TEvents, SD, D>): this;
/**
* Register a global middleware function.
* Middleware runs **before** any user message is processed.
*
* @example
* io.use((socket, ctx, next) => {
* console.log('Message received:', ctx);
* next();
* });
*/
use(fn: Middleware<TEvents, SD>): this;
attach(server: unknown, path: string): this;
destroy(): void;
}
//#endregion
//#region src/byte-socket-server-base.d.ts
type RequiredOptions = "middlewareTimeout" | "roomMiddlewareTimeout" | "authTimeout" | "broadcastRoom" | "onMiddlewareError" | "onMiddlewareTimeout" | "idleTimeout" | "sendPingsAutomatically";
declare abstract class ByteSocketServerBase<TEvents extends SocketEvents = SocketEvents, SD extends SocketData = SocketData, UpgradeCallback extends AnyCallback = AnyCallback> extends ByteSocketBase implements IByteSocket<TEvents, SD, UpgradeCallback> {
#private;
readonly lifecycle: ILifecycleServer<TEvents, SD, UpgradeCallback>;
readonly rooms: IRoomsServer<TEvents, SD>;
readonly sockets: Map<string, ISocket<TEvents, SD>>;
protected options: Omit<ByteSocketOptionsBase<TEvents, SD>, RequiredOptions | "debug" | "serialization" | "msgpackrOptions"> & Pick<Required<ByteSocketOptionsBase<TEvents, SD>>, RequiredOptions>;
constructor(options?: ByteSocketOptionsBase<TEvents, SD>);
abstract attach(server: unknown, path: string): this;
abstract destroy(): void;
protected abstract publishRaw(room: string, message: ServerOutgoingData, isBinary?: boolean, compress?: boolean): typeof this.rooms;
protected _destroy(): void;
emit<E extends StringNumberKeys<TEvents["emit"]>, D extends NonNullable<TEvents["emit"]>[E]>(event: E, data: D): this;
on<E extends StringNumberKeys<TEvents["listen"]>, D extends NonNullable<TEvents["listen"]>[E]>(event: E, callback: EventCallback<TEvents, SD, D>): this;
off<E extends StringNumberKeys<TEvents["listen"]>, D extends NonNullable<TEvents["listen"]>[E]>(event: E, callback?: EventCallback<TEvents, SD, D>): this;
once<E extends StringNumberKeys<TEvents["listen"]>, D extends NonNullable<TEvents["listen"]>[E]>(event: E, callback: EventCallback<TEvents, SD, D>): this;
use(fn: Middleware<TEvents, SD>): this;
get destroyed(): boolean;
protected message(socket: ISocket<TEvents, SD>, message: ServerIncomingData, isBinary: boolean): void;
protected close(socket: ISocket<TEvents, SD>, code: number, reason: Buffer | ArrayBuffer): void;
protected _runSyncHooks<Args extends Array<unknown>>(callbackSet: Set<AnyCallback> | undefined, args: Args, next: MiddlewareNext): void;
}
//#endregion
export { RoomEventMiddleware as _, IRoomsBulkServer as a, SocketData as b, ISocket as c, AuthCallback as d, AuthFunction as f, MiddlewareNext as g, Middleware as h, IRoomsBulkLifecycleServer as i, ISocketRooms as l, EventCallback as m, IByteSocket as n, IRoomsLifecycleServer as o, ByteSocketOptionsBase as p, ILifecycleServer as r, IRoomsServer as s, ByteSocketServerBase as t, ISocketRoomsBulk as u, ServerIncomingData as v, ServerOutgoingData as y };
//# sourceMappingURL=byte-socket-server-base-3oCYTtHD.d.ts.map
{"version":3,"file":"byte-socket-server-base-3oCYTtHD.d.ts","names":[],"sources":["../src/types.ts","../src/interfaces.ts","../src/byte-socket-server-base.ts"],"mappings":"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"}
import { AnyCallback, ByteSocketBase, ErrorContext, EventsForRooms, IByteSocketBase, LifecycleMessage, LifecycleTypes, MsgpackrOptions, SocketEvents, StringKeys, StringNumberKeys, UserMessage } from "@bytesocket/core";
import { UUID } from "node:crypto";
//#region src/types.d.ts
/** The data types actually received from outside.*/
type ServerIncomingData = Buffer | ArrayBuffer | Uint8Array;
/** The data types actually accepted by the server `server.send()` or `ws.send()` methods.*/
type ServerOutgoingData = string | ServerIncomingData;
/**
* Callback used by the authentication function to return the authentication result.
* @param payload - The authenticated user data to attach to the socket.
* @param error - Optional error if authentication failed.
*/
type AuthCallback = (payload: any, error?: Error) => void;
/**
* Authentication function signature. Called when a client sends an auth message.
*
* @typeParam SD - The socket data type (must extend `SocketData`).
* @typeParam D - The type of the authentication data sent by the client.
*
* @example
* const auth: AuthFunction = (socket, data, callback) => {
* if (data.token === "secret") {
* callback({ userId: 1 });
* } else {
* callback(null, new Error("Invalid token"));
* }
* };
*/
type AuthFunction<TEvents extends SocketEvents, SD extends SocketData, D = any> = (socket: ISocket<TEvents, SD>, data: D, callback: AuthCallback) => void;
/**
* Callback for global event listeners.
*
* @typeParam SD - The socket data type.
* @typeParam D - The type of the event data.
*
* @example
* socket.on("userJoined", (socket, data) => {
* console.log(`User ${data.userId} joined`);
* });
*/
type EventCallback<TEvents extends SocketEvents, SD extends SocketData, D> = (socket: ISocket<TEvents, SD>, data: D) => void;
/**
* Middleware function for room-scoped events. Can inspect or block the broadcast.
*
* @typeParam SD - The socket data type.
* @typeParam D - The type of the event data.
*
* @example
* io.rooms.on("chat", "message", (socket, data, next) => {
* if (data.text.includes("badword")) {
* next(new Error("Profanity not allowed"));
* } else {
* next();
* }
* });
*
* // Also supports async functions / Promises
* io.rooms.on("chat", "message", async (socket, data, next) => {
* const isValid = await validateMessage(data);
* if (!isValid) {
* return next(new Error("Invalid"));
* }
* next();
* });
*/
type RoomEventMiddleware<TEvents extends SocketEvents, SD extends SocketData, D> = (socket: ISocket<TEvents, SD>, data: D, next: MiddlewareNext) => void | Promise<void>;
/** Next function for middleware chains. Call `next()` to proceed, or `next(error)` to abort. */
type MiddlewareNext = (error?: unknown | null) => void;
/**
* Global middleware function. Runs before any user message is processed.
*
* @typeParam SD - The socket data type.
*
* @example
* io.use((socket, ctx, next) => {
* console.log("Received:", ctx);
* next();
* });
*/
type Middleware<TEvents extends SocketEvents = SocketEvents, SD extends SocketData = SocketData> = (socket: ISocket<TEvents, SD>, ctx: UserMessage, next: MiddlewareNext) => void | Promise<void>;
/**
* Data automatically attached to every socket by the server.
* Contains HTTP request information available during the WebSocket upgrade.
*/
type SocketData = {
/** Unique identifier for the socket (UUID v4). */socketKey: UUID; /** The url string from the upgrade request. */
url: string; /** The query string from the upgrade request. */
query: string; /** The `Host` header value. */
host: string; /** The `Cookie` header value. */
cookie: string; /** The `User-Agent` header value. */
userAgent: string; /** The `Authorization` header value. */
authorization: string; /** The `X-Forwarded-For` header value. */
xForwardedFor: string;
};
/**
* Configuration options for the ByteSocket server.
*
* @typeParam TEvents - The socket events definition.
* @typeParam SD - The socket data type (must extend `SocketData`).
*
* @example
* const io = new ByteSocket({
* debug: true,
* authTimeout: 10000,
* origins: ["https://example.com"],
* serialization: "binary",
* auth: (socket, data, callback) => {
* // validate token
* callback({ userId: 1 });
* }
* });
*/
type ByteSocketOptionsBase<TEvents extends SocketEvents = SocketEvents, SD extends SocketData = SocketData> = {
/** Enable debug logging to console. @default false */debug?: boolean; /** Timeout in milliseconds for global middleware execution. @default 5000 */
middlewareTimeout?: number; /** Timeout in milliseconds for room event middleware execution. @default 5000 */
roomMiddlewareTimeout?: number; /** Timeout for authentication response in milliseconds. @default 5000 */
authTimeout?: number; /** List of allowed origins for CORS. If empty, all origins are allowed. */
origins?: string[]; /** Serialization format: `"json"` or `"binary"` (msgpack). @default "binary" */
serialization?: "json" | "binary"; /** Room name used for global broadcasts. @default "__bytesocket_broadcast__" */
broadcastRoom?: string; /** Options passed directly to the underlying msgpackr Packr instance. */
msgpackrOptions?: MsgpackrOptions; /** Action to take when a global middleware error occurs. @default "ignore" */
onMiddlewareError?: "ignore" | "close" | ((error: unknown, socket: ISocket<TEvents, SD>) => void); /** Action to take when a global middleware times out. @default "ignore" */
onMiddlewareTimeout?: "ignore" | "close" | ((error: unknown, socket: ISocket<TEvents, SD>) => void); /** Authentication configuration. */
auth?: AuthFunction<TEvents, SD>;
/**
* Maximum milliseconds of inactivity (no messages received or pongs) before the connection is closed.
* Set to `0` to disable.
* @default 120000
*/
idleTimeout?: number;
/**
* Whether the server should automatically send WebSocket ping frames to keep
* the connection alive and detect dead clients.
* @default true
*/
sendPingsAutomatically?: boolean;
};
//#endregion
//#region src/interfaces.d.ts
/** Bulk operations for multiple rooms. */
interface ISocketRoomsBulk<TEvents extends SocketEvents> {
/**
* Events that can be emitted to multiple rooms at once.
*
* **Recommended pattern:** Use a union of `{ rooms: R; event: T }` objects:
*
* @example
* interface MyEvents extends SocketEvents {
* emitRooms:
* | { rooms: ['room1', 'room2']; event: { 'alert': { msg: string } } }
* | { rooms: ['roomA', 'roomB']; event: { 'message': { text: string } } };
*
* socket.rooms.bulk.emit(["room1", "room2"], "alert", { msg: "Hello" });
* }
*/
emit: <Rs extends NonNullable<TEvents["emitRooms"]>["rooms"], E extends StringNumberKeys<EventsForRooms<NonNullable<TEvents["emitRooms"]>, Rs>>, D extends NonNullable<EventsForRooms<NonNullable<TEvents["emitRooms"]>, Rs>>[E]>(rooms: Rs, event: E, data: D) => this;
/**
* Join multiple rooms.
* @example socket.rooms.bulk.join(["lobby", "notifications"]);
*/
join: (rooms: string[]) => this;
/**
* Leave multiple rooms.
* @example socket.rooms.bulk.leave(["lobby", "notifications"]);
*/
leave: (rooms: string[]) => this;
}
/**
* Room API available on individual socket instances (client-side or server-side socket).
* Provides methods to join/leave rooms and emit to rooms.
*
* @typeParam TEvents - The socket events definition.
*/
interface ISocketRooms<TEvents extends SocketEvents> {
/**
* Publishes a raw message to a specific room without applying any serialization or encoding.
*
* This method is useful for sending custom protocol messages or pre-encoded data directly
* to all sockets subscribed to the given room. It bypasses the built-in serialization layer,
* so you are responsible for ensuring that the message format matches what the clients expect.
*
* If the socket has been closed, this method does nothing.
*
* @param room - The name of the room to publish the message to.
* @param message - The raw message to send. Can be a `string` (UTF-8 text) or an `ArrayBuffer` / `Buffer` (binary data).
* @param isBinary - Optional. If `true`, the message is sent as a binary WebSocket frame.
* If `false` or omitted, the frame type is inferred from the type of `message`
* (`string` → text frame, `ArrayBuffer`/`Buffer` → binary frame).
* @param compress - Optional. If `true`, the message will be compressed using the WebSocket
* permessage-deflate extension (if negotiated with the client).
*
* @example
* // Send a JSON string to all sockets in the "lobby" room
* socket.rooms.publishRaw("lobby", JSON.stringify({ type: "announcement", text: "Hello!" }));
*
* @example
* // Send pre-encoded binary data (e.g., MessagePack) to the "game" room
* const packedData = msgpack.encode({ event: "move", x: 10, y: 20 });
* socket.rooms.publishRaw("game", packedData, true);
*/
publishRaw: (room: string, message: ServerOutgoingData, isBinary?: boolean, compress?: boolean) => this;
/**
* Emit a typed event to a specific room (server-side publish).
*
* @typeParam R - Room name (must be a key in `TEvents['emitRoom']`).
* @typeParam E - Event name.
* @typeParam D - Event data type.
* @param room - The target room.
* @param event - The event name.
* @param data - The event payload.
* @returns This server instance (for chaining).
*
* @example socket.rooms.emit("chat", "message", { text: "Hi" });
*/
emit: <R extends StringKeys<TEvents["emitRoom"]>, E extends StringNumberKeys<NonNullable<TEvents["emitRoom"]>[R]>, D extends NonNullable<TEvents["emitRoom"]>[R][E]>(room: R, event: E, data: D) => this;
/**
* Join a single room.
* @example socket.rooms.join("lobby");
*/
join: (room: string) => this;
/**
* Leave a single room.
* @example socket.rooms.leave("lobby");
*/
leave: (room: string) => this;
/**
* Get a list of rooms this socket is currently subscribed to.
* By default, the internal broadcast room is excluded.
*
* @param includeBroadcast - If `true`, includes the broadcast room in the result.
* @returns Array of room names.
*
* @example
* socket.rooms.list(); // ['chat', 'lobby']
* socket.rooms.list(true); // ['chat', 'lobby', '__bytesocket_broadcast__']
*/
list: (includeBroadcast?: boolean) => string[];
/** Bulk operations for multiple rooms. */
bulk: ISocketRoomsBulk<TEvents>;
}
/**
* Public API of an individual WebSocket connection.
*
* @typeParam TEvents - Event map type.
* @typeParam SD - Socket data type (extends `SocketData`).
*/
interface ISocket<TEvents extends SocketEvents = SocketEvents, SD extends SocketData = SocketData> {
/**
* Room management and room-scoped event emission.
*
* @example
* socket.rooms.join("chat");
* socket.rooms.emit("chat", "message", { text: "Hello!" });
* console.log(socket.rooms.list()); // ["chat"]
*/
readonly rooms: ISocketRooms<TEvents>;
/** Unique identifier for the socket (same as `userData.socketKey`). */
readonly id: string;
/**
* Payload attached during successful authentication.
* Available in middleware and event listeners.
*
* @example
* io.on("chat", (socket, data) => {
* console.log(`Message from ${socket.payload.username}`);
* });
*/
payload: any;
/**
* Mutable object for storing arbitrary data during the socket's lifetime.
* Useful for passing data between middleware and event handlers.
*
* @example
* io.use((socket, ctx, next) => {
* socket.locals.requestId = randomUUID();
* next();
* });
*/
locals: any;
/**
* Whether the socket has completed authentication (or auth is disabled).
* Returns `true` if no auth is configured, or if authentication succeeded.
*/
readonly isAuthenticated: boolean;
/** Whether the socket has been closed. */
readonly isClosed: boolean;
/**
* Whether the socket is currently able to send messages.
* Returns `true` if the WebSocket is open and authentication (if configured) has succeeded.
* Useful for checking readiness before calling `sendRaw()` or `rooms.publishRaw()`.
* No need to use it with `emit()` or `send()` because they already use it under the hood.
*
* @example
* if (socket.canSend) {
* socket.sendRaw('PROTOCOL: custom-v1');
* }
*/
readonly canSend: boolean;
/**
* The user data object attached during the WebSocket upgrade.
* Contains HTTP request headers and other metadata.
*
* @example
* console.log(socket.userData.socketKey);
*/
readonly userData: SD;
/**
* The path component of the URL requested by the client during the
* WebSocket upgrade.
*
* @example
* // If the client connected to `wss://example.com/socket?room=lobby`,
* // this will be `"/socket"`.
*/
readonly url: string;
/**
* The raw query string from the WebSocket upgrade request.
*
* @example
* // If the client connected to `wss://example.com/socket?room=lobby&token=abc`,
* // this will be `"room=lobby&token=abc"`.
* const query = socket.query;
* const params = new URLSearchParams(socket.query);
* console.log(params.get('room')); // "lobby"
*/
readonly query: string;
/**
* The `Cookie` header from the WebSocket upgrade request.
*
* @example
* // Useful for session handling when not using the Authorization header.
* const cookies = socket.cookie;
* const sessionId = parseCookies(cookies)?.sessionId;
*/
readonly cookie: string;
/**
* The `Authorization` header from the WebSocket upgrade request.
* Typically contains a Bearer token or Basic auth credentials.
*
* @example
* const authHeader = socket.authorization;
* if (authHeader?.startsWith('Bearer ')) {
* const token = authHeader.slice(7);
* // validate token...
* }
*/
readonly authorization: string;
/**
* The `User-Agent` header from the WebSocket upgrade request.
*
* @example
* console.log(`Client: ${socket.userAgent}`);
* // "Client: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ..."
*/
readonly userAgent: string;
/**
* The `Host` header from the WebSocket upgrade request.
* Includes the domain and (optionally) port the client used to connect.
*
* @example
* console.log(socket.host); // "api.example.com"
*/
readonly host: string;
/**
* The `X-Forwarded-For` header from the WebSocket upgrade request.
* Contains the originating client IP when behind a proxy or load balancer.
*
* @example
* const clientIp = socket.xForwardedFor?.split(',')[0].trim() || 'unknown';
* console.log(`Client IP: ${clientIp}`);
*/
readonly xForwardedFor: string;
/**
* Emit a typed global event to this socket only.
*
* @typeParam E - Event name (must be a key in `TEvents['emit']`).
* @typeParam D - Event data type.
* @param event - The event name.
* @param data - The event payload.
* @returns This socket instance (for chaining).
*
* @example
* socket.emit("privateMessage", { from: "server", text: "Hello" });
*/
emit<E extends StringNumberKeys<TEvents["emit"]>, D extends NonNullable<TEvents["emit"]>[E]>(event: E, data: D): this;
/**
* Send a raw message (string or binary) directly to this socket.
* Bypasses serialization. Useful for custom protocols.
*
* @param message - The message to send.
* @param isBinary - Whether to send as binary frame.
* @default true `if message is not a string`.
* @param compress - Whether to use permessage-deflate compression.
* @returns This socket instance.
*
* @example
* socket.sendRaw(JSON.stringify({ custom: "data" }));
*/
sendRaw(message: ServerOutgoingData, isBinary?: boolean, compress?: boolean): this;
/**
* Send any lifecycle or user message to this socket.
* Automatically encodes according to the configured serialization.
* You typically use `emit()` or `broadcast()` instead.
*
* @param payload - The message to send (user message or lifecycle message).
* @returns This socket instance.
*
* @example
* socket.send({ event: "echo", data: { message: "hello" } });
*/
send<R extends string, E extends string | number, D>(payload: LifecycleMessage<R, D> | UserMessage<R, E, D>): this;
/**
* Broadcast a global event to all **other** connected sockets.
* The publishing socket does **not** receive the message.
*
* @typeParam E - Event name.
* @typeParam D - Event data type.
* @param event - The event name.
* @param data - The event payload.
* @returns This socket instance.
*
* @example
* socket.broadcast("userJoined", { userId: socket.id });
*/
broadcast<E extends StringNumberKeys<TEvents["emit"]>, D extends NonNullable<TEvents["emit"]>[E]>(event: E, data: D): this;
/**
* Close the WebSocket connection gracefully.
*
* @param code - WebSocket close code. @default 1000
* @param reason - Close reason string. @default "normal"
*
* @example
* socket.close(1008, "Policy violation");
*/
close(code?: number, reason?: string): void;
/**
* Handle an incoming auth message. Sets up timeout, calls user-provided auth function,
* and manages the success/failure lifecycle.
*
* @internal
*/
_handleAuth<D>(parsed: {
type: LifecycleTypes.auth;
data: D;
} | null, auth: AuthFunction<TEvents, SD, D> | undefined, authTimeout: number, next: MiddlewareNext): void;
}
/**
* Lifecycle event API available on the ByteSocket server instance.
* Allows listening to connection, authentication, message, close, and error events.
*
* @typeParam TEvents - The socket events definition.
* @typeParam SD - The socket data type.
*/
interface ILifecycleServer<TEvents extends SocketEvents, SD extends SocketData, UpgradeCallback extends AnyCallback> {
/** Register a listener for the HTTP upgrade phase. */
onUpgrade: (callback: UpgradeCallback) => this;
/** Remove a listener for the HTTP upgrade phase. */
offUpgrade: (callback?: UpgradeCallback) => this;
/** Register a one-time listener for the HTTP upgrade phase. */
onceUpgrade: (callback: UpgradeCallback) => this;
/** Register a listener for socket open (after successful auth). */
onOpen: (callback: (socket: ISocket<TEvents, SD>) => void) => this;
/** Remove a listener for socket open. */
offOpen: (callback?: (socket: ISocket<TEvents, SD>) => void) => this;
/** Register a one-time listener for socket open. */
onceOpen: (callback: (socket: ISocket<TEvents, SD>) => void) => this;
/** Register a listener for authentication success. */
onAuthSuccess: (callback: (socket: ISocket<TEvents, SD>) => void) => this;
/** Remove a listener for authentication success. */
offAuthSuccess: (callback?: (socket: ISocket<TEvents, SD>) => void) => this;
/** Register a one-time listener for authentication success. */
onceAuthSuccess: (callback: (socket: ISocket<TEvents, SD>) => void) => this;
/** Register a listener for authentication failure. */
onAuthError: (callback: (socket: ISocket<TEvents, SD>, ctx: ErrorContext) => void) => this;
/** Remove a listener for authentication failure. */
offAuthError: (callback?: (socket: ISocket<TEvents, SD>, ctx: ErrorContext) => void) => this;
/** Register a one-time listener for authentication failure. */
onceAuthError: (callback: (socket: ISocket<TEvents, SD>, ctx: ErrorContext) => void) => this;
/** Register a listener for raw incoming messages. */
onMessage: (callback: (socket: ISocket<TEvents, SD>, data: ServerIncomingData, isBinary: boolean) => void) => this;
/** Remove a listener for raw incoming messages. */
offMessage: (callback?: (socket: ISocket<TEvents, SD>, data: ServerIncomingData, isBinary: boolean) => void) => this;
/** Register a one-time listener for raw incoming messages. */
onceMessage: (callback: (socket: ISocket<TEvents, SD>, data: ServerIncomingData, isBinary: boolean) => void) => this;
/** Register a listener for socket close. */
onClose: (callback: (socket: ISocket<TEvents, SD>, code: number, reason: ServerIncomingData) => void) => this;
/** Remove a listener for socket close. */
offClose: (callback?: (socket: ISocket<TEvents, SD>, code: number, reason: ServerIncomingData) => void) => this;
/** Register a one-time listener for socket close. */
onceClose: (callback: (socket: ISocket<TEvents, SD>, code: number, reason: ServerIncomingData) => void) => this;
/** Register a listener for errors. */
onError: (callback: (socket: ISocket<TEvents, SD> | null, ctx: ErrorContext) => void) => this;
/** Remove a listener for errors. */
offError: (callback?: (socket: ISocket<TEvents, SD> | null, ctx: ErrorContext) => void) => this;
/** Register a one-time listener for errors. */
onceError: (callback: (socket: ISocket<TEvents, SD> | null, ctx: ErrorContext) => void) => this;
}
/** Lifecycle hooks for room join/leave (single rooms). */
interface IRoomsLifecycleServer<TEvents extends SocketEvents, SD extends SocketData> {
/**
* Register a guard for single room join requests.
* Call `next()` to allow, `next(error)` to reject.
*
* @example
* io.rooms.lifecycle.onJoin((socket, room, next) => {
* if (room === 'admin' && !socket.payload?.isAdmin) {
* next(new Error('Not authorized'));
* } else {
* next();
* }
* });
*/
onJoin: (callback: (socket: ISocket<TEvents, SD>, room: string, next: MiddlewareNext) => void) => this;
/** Remove a guard for single room join requests. */
offJoin: (callback?: (socket: ISocket<TEvents, SD>, room: string, next: MiddlewareNext) => void) => this;
/** Register a one-time guard for single room join requests. */
onceJoin: (callback: (socket: ISocket<TEvents, SD>, room: string, next: MiddlewareNext) => void) => this;
/** Register a guard for single room leave requests. */
onLeave: (callback: (socket: ISocket<TEvents, SD>, room: string, next: MiddlewareNext) => void) => this;
/** Remove a guard for single room leave requests. */
offLeave: (callback?: (socket: ISocket<TEvents, SD>, room: string, next: MiddlewareNext) => void) => this;
/** Register a one-time guard for single room leave requests. */
onceLeave: (callback: (socket: ISocket<TEvents, SD>, room: string, next: MiddlewareNext) => void) => this;
}
/** Lifecycle hooks for bulk room operations. */
interface IRoomsBulkLifecycleServer<TEvents extends SocketEvents, SD extends SocketData> {
/** Register a guard for bulk room join requests. */
onJoin: (callback: (socket: ISocket<TEvents, SD>, rooms: string[], next: MiddlewareNext) => void) => this;
/** Remove a guard for bulk room join requests. */
offJoin: (callback?: (socket: ISocket<TEvents, SD>, rooms: string[], next: MiddlewareNext) => void) => this;
/** Register a one-time guard for bulk room join requests. */
onceJoin: (callback: (socket: ISocket<TEvents, SD>, rooms: string[], next: MiddlewareNext) => void) => this;
/** Register a guard for bulk room leave requests. */
onLeave: (callback: (socket: ISocket<TEvents, SD>, rooms: string[], next: MiddlewareNext) => void) => this;
/** Remove a guard for bulk room leave requests. */
offLeave: (callback?: (socket: ISocket<TEvents, SD>, rooms: string[], next: MiddlewareNext) => void) => this;
/** Register a one-time guard for bulk room leave requests. */
onceLeave: (callback: (socket: ISocket<TEvents, SD>, rooms: string[], next: MiddlewareNext) => void) => this;
}
interface IRoomsBulkServer<TEvents extends SocketEvents, SD extends SocketData> {
/**
* Emit a typed event to multiple rooms at once.
*
* @typeParam Rs - The array of room names.
* @typeParam E - Event name.
* @typeParam D - Event data type.
*
* @example
* interface MyEvents extends SocketEvents {
* emitRooms:
* | { rooms: ['room1', 'room2']; event: { 'alert': { msg: string } } }
* | { rooms: ['roomA', 'roomB']; event: { 'message': { text: string } } };
*
* io.rooms.bulk.emit(['room1', 'room2'], 'alert', { msg: 'Hello both!' });
*/
emit: <Rs extends NonNullable<TEvents["emitRooms"]>["rooms"], E extends StringNumberKeys<EventsForRooms<NonNullable<TEvents["emitRooms"]>, Rs>>, D extends NonNullable<EventsForRooms<NonNullable<TEvents["emitRooms"]>, Rs>>[E]>(rooms: Rs, event: E, data: D) => this;
/** Lifecycle hooks for bulk room operations. */
lifecycle: IRoomsBulkLifecycleServer<TEvents, SD>;
}
/**
* Room management API available on the ByteSocket server instance.
* Provides methods to emit to rooms, publish raw data, and attach room-level middleware.
*
* @typeParam TEvents - The socket events definition.
* @typeParam SD - The socket data type.
*/
interface IRoomsServer<TEvents extends SocketEvents, SD extends SocketData> {
/**
* Publishes a raw message to all sockets subscribed to the given room.
*
* This method broadcasts the data directly to all connected sockets in the room
* using the underlying `ws` server, **without** applying any encoding,
* serialization, or lifecycle processing. It is useful for broadcasting
* custom-formatted messages, pre-encoded payloads, or implementing custom protocols.
*
* If the server instance has been destroyed, this method does nothing.
*
* @param room - The room name to publish the message to. All sockets that have joined this
* room (including the global broadcast room) will receive the message.
* @param message - The raw data to send. Accepts a `string` (sent as a UTF-8 text frame) or
* an `ArrayBuffer` / `Buffer` (sent as a binary frame).
* @param isBinary - Optional. If `true`, forces the message to be sent as a binary WebSocket
* frame. If `false` or omitted, the frame type is inferred from the type of
* `message` (`string` → text, `ArrayBuffer`/`Buffer` → binary).
* @param compress - Optional. If `true`, the message will be compressed using the WebSocket
* permessage-deflate extension (if negotiated with the clients).
*
* @example
* // Broadcast a JSON string to the "lobby" room
* io.rooms.publishRaw("lobby", JSON.stringify({ type: "announcement", text: "Server restart in 5m" }));
*
* @example
* // Broadcast pre-encoded MessagePack data to the "lobby" room
* const packed = msgpack.encode({ event: "system", status: "ok" });
* io.rooms.publishRaw("lobby", packed, true);
*
* @example
* // Send compressed binary data
* const buffer = new Uint8Array([1, 2, 3]);
* io.rooms.publishRaw("updates", buffer, true, true);
*/
publishRaw: (room: string, message: ServerOutgoingData, isBinary?: boolean, compress?: boolean) => this;
/**
* Emit a typed event to a specific room (server-side publish).
*
* @typeParam R - Room name (must be a key in `TEvents['emitRoom']`).
* @typeParam E - Event name.
* @typeParam D - Event data type.
*
* @example
* io.rooms.emit('chat', 'message', { text: 'Hello everyone' });
*/
emit: <R extends StringKeys<TEvents["emitRoom"]>, E extends StringNumberKeys<NonNullable<TEvents["emitRoom"]>[R]>, D extends NonNullable<TEvents["emitRoom"]>[R][E]>(room: R, event: E, data: D) => this;
/** Register a room event middleware. */
on: <R extends StringKeys<TEvents["listenRoom"]>, E extends StringNumberKeys<NonNullable<TEvents["listenRoom"]>[R]>, D extends NonNullable<TEvents["listenRoom"]>[R][E]>(room: R, event: E, callback: RoomEventMiddleware<TEvents, SD, D>) => this;
/** Remove a room event middleware. */
off: <R extends StringKeys<TEvents["listenRoom"]>, E extends StringNumberKeys<NonNullable<TEvents["listenRoom"]>[R]>, D extends NonNullable<TEvents["listenRoom"]>[R][E]>(room: R, event?: E, callback?: RoomEventMiddleware<TEvents, SD, D>) => this;
/** Register a one-time room event middleware. */
once: <R extends StringKeys<TEvents["listenRoom"]>, E extends StringNumberKeys<NonNullable<TEvents["listenRoom"]>[R]>, D extends NonNullable<TEvents["listenRoom"]>[R][E]>(room: R, event: E, callback: RoomEventMiddleware<TEvents, SD, D>) => this;
/** Lifecycle hooks for room join/leave (single rooms). */
lifecycle: IRoomsLifecycleServer<TEvents, SD>;
/** Bulk operations for multiple rooms. */
bulk: IRoomsBulkServer<TEvents, SD>;
}
/**
* Public API of a ByteSocket server instance.
*
* Manages WebSocket connections, rooms, middleware, and event routing.
* The implementation class {@link ByteSocket} should `implement` this interface.
*
* @typeParam TEvents - Event map (extends `SocketEvents`) defining the shape of
* all emit/listen events (global and room‑scoped).
* @typeParam SD - Socket data type that extends `SocketData`.
*/
interface IByteSocket<TEvents extends SocketEvents = SocketEvents, SD extends SocketData = SocketData, UpgradeCallback extends AnyCallback = AnyCallback> extends IByteSocketBase {
/**
* Lifecycle event listeners for connection, authentication, and errors.
*
* @example
* io.lifecycle.onOpen((socket) => console.log('Connected!'));
* io.lifecycle.onAuthError((socket, ctx) => console.error('Auth failed', ctx.error));
* io.lifecycle.onClose((socket, code, msg) => console.log('Closed', code));
*/
readonly lifecycle: ILifecycleServer<TEvents, SD, UpgradeCallback>;
/**
* Room management, room-scoped event emission, and room lifecycle hooks.
*
* @example
* io.rooms.emit('lobby', 'announcement', { text: 'Welcome!' });
* io.rooms.on('chat', 'message', (socket, data, next) => { ... });
* io.rooms.lifecycle.onJoin((socket, room, next) => {
* if (room === 'admin') next(new Error('Not allowed'));
* else next();
* });
*/
readonly rooms: IRoomsServer<TEvents, SD>;
/**
* Map of all currently connected sockets, keyed by socket ID.
*
* **Do not modify this map directly** - it is managed internally.
*
* @example
* for (const [id, socket] of io.sockets) {
* socket.emit('ping', undefined);
* }
*/
readonly sockets: Map<string, ISocket<TEvents, SD>>;
/**
* Indicates whether the server instance has been permanently destroyed.
*
* Once `true`, the instance cannot be reused; all connections have been closed and
* internal resources released. Use {@link destroy} to initiate shutdown.
*
* @example
* if (io.destroyed) {
* console.log('Server is shut down');
* }
*/
readonly destroyed: boolean;
/**
* Emit a global event to all connected sockets.
*
* @typeParam E - Event name (must be a key in `TEvents['emit']`).
* @typeParam D - Event data type.
*
* @example io.emit('userJoined', { userId: '123' });
*/
emit<E extends StringNumberKeys<TEvents["emit"]>, D extends NonNullable<TEvents["emit"]>[E]>(event: E, data: D): this;
/**
* Register a permanent listener for global events.
*
* @typeParam E - Event name (must be a key in `TEvents['listen']`).
*
* @example io.on('userJoined', (socket, data) => { console.log(data.userId); });
*/
on<E extends StringNumberKeys<TEvents["listen"]>, D extends NonNullable<TEvents["listen"]>[E]>(event: E, callback: EventCallback<TEvents, SD, D>): this;
/**
* Remove a listener for global events.
* If no callback is provided, **all** listeners for that event are removed.
*
* @example io.off('userJoined', myCallback);
*/
off<E extends StringNumberKeys<TEvents["listen"]>, D extends NonNullable<TEvents["listen"]>[E]>(event: E, callback?: EventCallback<TEvents, SD, D>): this;
/**
* Register a one-time listener for a global event.
* The callback is removed after the first invocation.
*
* @example io.once('userJoined', (socket, data) => { console.log('First join'); });
*/
once<E extends StringNumberKeys<TEvents["listen"]>, D extends NonNullable<TEvents["listen"]>[E]>(event: E, callback: EventCallback<TEvents, SD, D>): this;
/**
* Register a global middleware function.
* Middleware runs **before** any user message is processed.
*
* @example
* io.use((socket, ctx, next) => {
* console.log('Message received:', ctx);
* next();
* });
*/
use(fn: Middleware<TEvents, SD>): this;
attach(server: unknown, path: string): this;
destroy(): void;
}
//#endregion
//#region src/byte-socket-server-base.d.ts
type RequiredOptions = "middlewareTimeout" | "roomMiddlewareTimeout" | "authTimeout" | "broadcastRoom" | "onMiddlewareError" | "onMiddlewareTimeout" | "idleTimeout" | "sendPingsAutomatically";
declare abstract class ByteSocketServerBase<TEvents extends SocketEvents = SocketEvents, SD extends SocketData = SocketData, UpgradeCallback extends AnyCallback = AnyCallback> extends ByteSocketBase implements IByteSocket<TEvents, SD, UpgradeCallback> {
#private;
readonly lifecycle: ILifecycleServer<TEvents, SD, UpgradeCallback>;
readonly rooms: IRoomsServer<TEvents, SD>;
readonly sockets: Map<string, ISocket<TEvents, SD>>;
protected options: Omit<ByteSocketOptionsBase<TEvents, SD>, RequiredOptions | "debug" | "serialization" | "msgpackrOptions"> & Pick<Required<ByteSocketOptionsBase<TEvents, SD>>, RequiredOptions>;
constructor(options?: ByteSocketOptionsBase<TEvents, SD>);
abstract attach(server: unknown, path: string): this;
abstract destroy(): void;
protected abstract publishRaw(room: string, message: ServerOutgoingData, isBinary?: boolean, compress?: boolean): typeof this.rooms;
protected _destroy(): void;
emit<E extends StringNumberKeys<TEvents["emit"]>, D extends NonNullable<TEvents["emit"]>[E]>(event: E, data: D): this;
on<E extends StringNumberKeys<TEvents["listen"]>, D extends NonNullable<TEvents["listen"]>[E]>(event: E, callback: EventCallback<TEvents, SD, D>): this;
off<E extends StringNumberKeys<TEvents["listen"]>, D extends NonNullable<TEvents["listen"]>[E]>(event: E, callback?: EventCallback<TEvents, SD, D>): this;
once<E extends StringNumberKeys<TEvents["listen"]>, D extends NonNullable<TEvents["listen"]>[E]>(event: E, callback: EventCallback<TEvents, SD, D>): this;
use(fn: Middleware<TEvents, SD>): this;
get destroyed(): boolean;
protected message(socket: ISocket<TEvents, SD>, message: ServerIncomingData, isBinary: boolean): void;
protected close(socket: ISocket<TEvents, SD>, code: number, reason: Buffer | ArrayBuffer): void;
protected _runSyncHooks<Args extends Array<unknown>>(callbackSet: Set<AnyCallback> | undefined, args: Args, next: MiddlewareNext): void;
}
//#endregion
export { RoomEventMiddleware as _, IRoomsBulkServer as a, SocketData as b, ISocket as c, AuthCallback as d, AuthFunction as f, MiddlewareNext as g, Middleware as h, IRoomsBulkLifecycleServer as i, ISocketRooms as l, EventCallback as m, IByteSocket as n, IRoomsLifecycleServer as o, ByteSocketOptionsBase as p, ILifecycleServer as r, IRoomsServer as s, ByteSocketServerBase as t, ISocketRoomsBulk as u, ServerIncomingData as v, ServerOutgoingData as y };
//# sourceMappingURL=byte-socket-server-base-Cri0yUAN.d.cts.map
{"version":3,"file":"byte-socket-server-base-Cri0yUAN.d.cts","names":[],"sources":["../src/types.ts","../src/interfaces.ts","../src/byte-socket-server-base.ts"],"mappings":"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"}

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

+42
-33

@@ -130,3 +130,3 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });

this.#authState = _bytesocket_core.AuthState.pending;
this.#authTimer = setTimeout(() => {
if (authTimeout > 0) this.#authTimer = setTimeout(() => {
if (!this.isClosed && !this.isAuthenticated) {

@@ -216,9 +216,9 @@ const err = /* @__PURE__ */ new Error("Auth timeout");

...options,
middlewareTimeout: options.middlewareTimeout ?? 5e3,
roomMiddlewareTimeout: options.roomMiddlewareTimeout ?? 5e3,
authTimeout: options.authTimeout ?? 5e3,
middlewareTimeout: options.middlewareTimeout ?? 0,
roomMiddlewareTimeout: options.roomMiddlewareTimeout ?? 0,
authTimeout: options.authTimeout ?? 0,
broadcastRoom: options.broadcastRoom ?? "__bytesocket_broadcast__",
onMiddlewareError: options.onMiddlewareError ?? "ignore",
onMiddlewareTimeout: options.onMiddlewareTimeout ?? "ignore",
idleTimeout: options.idleTimeout ?? 120,
idleTimeout: options.idleTimeout ?? 12e4,
sendPingsAutomatically: options.sendPingsAutomatically ?? true

@@ -442,2 +442,5 @@ };

}
#isPromiseLike(value) {
return !!value && typeof value.then === "function";
}
#runMiddlewares(socket, ctx, finalCallback) {

@@ -474,3 +477,3 @@ let index = 0;

let timeoutId = null;
const execution = new Promise((resolve, reject) => {
const tasks = [new Promise((resolve, reject) => {
try {

@@ -483,3 +486,3 @@ const result = middleware(socket, ctx, (err) => {

});
if (result instanceof Promise) result.then(() => {
if (this.#isPromiseLike(result)) result.then(() => {
if (!called) {

@@ -501,14 +504,17 @@ called = true;

}
});
const timeout = new Promise((_, reject) => {
timeoutId = setTimeout(() => {
if (!called) {
called = true;
const timeoutError = /* @__PURE__ */ new Error(`Middleware timeout after ${this.options.middlewareTimeout}ms`);
timeoutError.name = "TimeoutError";
reject(timeoutError);
}
}, this.options.middlewareTimeout);
});
Promise.race([execution, timeout]).then(() => next()).catch((err) => next(err)).finally(() => {
})];
if (this.options.middlewareTimeout > 0) {
const timeout = new Promise((_, reject) => {
timeoutId = setTimeout(() => {
if (!called) {
called = true;
const timeoutError = /* @__PURE__ */ new Error(`Middleware timeout after ${this.options.middlewareTimeout}ms`);
timeoutError.name = "TimeoutError";
reject(timeoutError);
}
}, this.options.middlewareTimeout);
});
tasks.push(timeout);
}
Promise.race(tasks).then(() => next()).catch((err) => next(err)).finally(() => {
if (timeoutId) clearTimeout(timeoutId);

@@ -788,3 +794,3 @@ });

let timeoutId = null;
const execution = new Promise((resolve, reject) => {
const tasks = [new Promise((resolve, reject) => {
try {

@@ -797,3 +803,3 @@ const result = callback(...args, (err) => {

});
if (result instanceof Promise) result.then(() => {
if (this.#isPromiseLike(result)) result.then(() => {
if (!called) {

@@ -815,14 +821,17 @@ called = true;

}
});
const timeout = new Promise((_, reject) => {
timeoutId = setTimeout(() => {
if (!called) {
called = true;
const timeoutError = /* @__PURE__ */ new Error(`Room middleware timeout after ${this.options.roomMiddlewareTimeout}ms`);
timeoutError.name = "TimeoutError";
reject(timeoutError);
}
}, this.options.roomMiddlewareTimeout);
});
Promise.race([execution, timeout]).then(() => next()).catch((err) => next(err)).finally(() => {
})];
if (this.options.roomMiddlewareTimeout > 0) {
const timeout = new Promise((_, reject) => {
timeoutId = setTimeout(() => {
if (!called) {
called = true;
const timeoutError = /* @__PURE__ */ new Error(`Room middleware timeout after ${this.options.roomMiddlewareTimeout}ms`);
timeoutError.name = "TimeoutError";
reject(timeoutError);
}
}, this.options.roomMiddlewareTimeout);
});
tasks.push(timeout);
}
Promise.race(tasks).then(() => next()).catch((err) => next(err)).finally(() => {
if (timeoutId) clearTimeout(timeoutId);

@@ -829,0 +838,0 @@ });

@@ -1,1 +0,1 @@

{"version":3,"file":"index.cjs","names":["AuthState","#authState","#closed","#encode","#publish","#publishMany","#joinRooms","#leaveRooms","#clearAuthTimer","#authTimer","#setAuthFailed","#setAuthSuccess","#handleNoAuth","#sendUnchecked","LifecycleTypes","ByteSocketBase","LifecycleTypes","#publish","#onRoom","#offRoom","#onceRoom","#publishMany","#destroyed","#middlewares","#rawMessageDescription","#handleAuthMessage","#handleJoinRoomMessage","#handleLeaveRoomMessage","#handleJoinRoomsMessage","#handleLeaveRoomsMessage","#runMiddlewares","#handleRoomsEventMessage","#handleRoomEventMessage","#handleEventMessage","#runAsyncHooksOrNext"],"sources":["../src/socket-server-base.ts","../src/byte-socket-server-base.ts"],"sourcesContent":["// packages/server/src/socket-server-base.ts\nimport {\n\tAuthState,\n\tLifecycleTypes,\n\ttype ErrorContext,\n\ttype EventsForRooms,\n\ttype LifecycleMessage,\n\ttype SocketEvents,\n\ttype StringKeys,\n\ttype StringNumberKeys,\n\ttype UserMessage,\n} from \"@bytesocket/core\";\nimport type { ISocket, ISocketRooms } from \"./interfaces\";\nimport type { AuthFunction, MiddlewareNext, ServerOutgoingData, SocketData } from \"./types\";\n\nexport abstract class SocketServerBase<TEvents extends SocketEvents = SocketEvents, SD extends SocketData = SocketData> implements ISocket<\n\tTEvents,\n\tSD\n> {\n\treadonly rooms: ISocketRooms<TEvents>;\n\n\tpayload: any = {};\n\tlocals: any = {};\n\n\t#encode: <R extends string, E extends string | number, D>(\n\t\tpayload: LifecycleMessage<R, D> | UserMessage<R, E, D>,\n\t) => string | Buffer<ArrayBufferLike>;\n\t#authState: AuthState = AuthState.idle;\n\t#authTimer: ReturnType<typeof setTimeout> | null = null;\n\t#closed: boolean = false;\n\n\tget isAuthenticated(): boolean {\n\t\treturn this.#authState === AuthState.none || this.#authState === AuthState.success;\n\t}\n\tget isClosed(): boolean {\n\t\treturn this.#closed;\n\t}\n\tget canSend(): boolean {\n\t\treturn !this.#closed && this.isAuthenticated;\n\t}\n\n\tabstract readonly userData: SD;\n\tget id(): string {\n\t\treturn this.userData.socketKey;\n\t}\n\tget url(): string {\n\t\treturn this.userData.url;\n\t}\n\tget query(): string {\n\t\treturn this.userData.query;\n\t}\n\tget cookie(): string {\n\t\treturn this.userData.cookie;\n\t}\n\tget authorization(): string {\n\t\treturn this.userData.authorization;\n\t}\n\tget userAgent(): string {\n\t\treturn this.userData.userAgent;\n\t}\n\tget host(): string {\n\t\treturn this.userData.host;\n\t}\n\tget xForwardedFor(): string {\n\t\treturn this.userData.xForwardedFor;\n\t}\n\n\tprotected abstract readonly broadcastRoom: string;\n\n\tconstructor(\n\t\tencode: <R extends string, E extends string | number, D>(\n\t\t\tpayload: LifecycleMessage<R, D> | UserMessage<R, E, D>,\n\t\t) => string | Buffer<ArrayBufferLike>,\n\t) {\n\t\tthis.#encode = encode;\n\t\tthis.rooms = {\n\t\t\tpublishRaw: this.publishRaw.bind(this),\n\t\t\temit: this.#publish.bind(this),\n\t\t\tjoin: this.joinRoom.bind(this),\n\t\t\tleave: this.leaveRoom.bind(this),\n\t\t\tlist: this.getRoomList.bind(this),\n\t\t\tbulk: {\n\t\t\t\temit: this.#publishMany.bind(this),\n\t\t\t\tjoin: this.#joinRooms.bind(this),\n\t\t\t\tleave: this.#leaveRooms.bind(this),\n\t\t\t},\n\t\t};\n\t}\n\n\tabstract sendRaw(message: ServerOutgoingData, isBinary?: boolean, compress?: boolean): this;\n\n\tprotected abstract getRoomList(includeBroadcast?: boolean): string[];\n\n\tprotected abstract publishRaw(room: string, message: ServerOutgoingData, isBinary?: boolean, compress?: boolean): typeof this.rooms;\n\n\tprotected abstract joinRoom(room: string): typeof this.rooms;\n\n\tprotected abstract leaveRoom(room: string): typeof this.rooms;\n\n\tabstract close(code?: number, reason?: string): void;\n\n\tprotected startHeartbeat(): void {}\n\n\tprotected clearHeartbeat(): void {}\n\n\temit<E extends StringNumberKeys<TEvents[\"emit\"]>, D extends NonNullable<TEvents[\"emit\"]>[E]>(event: E, data: D): this {\n\t\tthis.send({ event, data });\n\t\treturn this;\n\t}\n\n\tsend<R extends string, E extends string | number, D>(payload: LifecycleMessage<R, D> | UserMessage<R, E, D>): this {\n\t\tif (!this.canSend) {\n\t\t\treturn this;\n\t\t}\n\t\tconst message = this.#encode(payload);\n\t\tthis.sendRaw(message);\n\t\treturn this;\n\t}\n\n\tbroadcast<E extends StringNumberKeys<TEvents[\"emit\"]>, D extends NonNullable<TEvents[\"emit\"]>[E]>(event: E, data: D): this {\n\t\tif (!this.canSend) {\n\t\t\treturn this;\n\t\t}\n\t\tconst message = this.#encode({ event, data });\n\t\tthis.publishRaw(this.broadcastRoom, message);\n\t\treturn this;\n\t}\n\n\t#sendUnchecked<R extends string, E extends string | number, D>(payload: LifecycleMessage<R, D> | UserMessage<R, E, D>): void {\n\t\tif (this.#closed) {\n\t\t\treturn;\n\t\t}\n\t\tconst message = this.#encode(payload);\n\t\tthis.sendRaw(message);\n\t}\n\n\t#publish<\n\t\tR extends StringKeys<TEvents[\"emitRoom\"]>,\n\t\tE extends StringNumberKeys<NonNullable<TEvents[\"emitRoom\"]>[R]>,\n\t\tD extends NonNullable<TEvents[\"emitRoom\"]>[R][E],\n\t>(room: R, event: E, data: D): typeof this.rooms {\n\t\tif (!this.canSend) {\n\t\t\treturn this.rooms;\n\t\t}\n\t\tconst message = this.#encode({ room, event, data });\n\t\tthis.publishRaw(room, message);\n\t\treturn this.rooms;\n\t}\n\n\t#publishMany<\n\t\tRs extends NonNullable<TEvents[\"emitRooms\"]>[\"rooms\"],\n\t\tE extends StringNumberKeys<EventsForRooms<NonNullable<TEvents[\"emitRooms\"]>, Rs>>,\n\t\tD extends NonNullable<EventsForRooms<NonNullable<TEvents[\"emitRooms\"]>, Rs>>[E],\n\t>(rooms: Rs, event: E, data: D): typeof this.rooms.bulk {\n\t\tif (!this.canSend) {\n\t\t\treturn this.rooms.bulk;\n\t\t}\n\t\tconst message = this.#encode({ rooms, event, data });\n\t\tfor (const room of rooms) {\n\t\t\tthis.publishRaw(room, message);\n\t\t}\n\t\treturn this.rooms.bulk;\n\t}\n\n\t#joinRooms(rooms: string[]): typeof this.rooms.bulk {\n\t\tif (!this.canSend) {\n\t\t\treturn this.rooms.bulk;\n\t\t}\n\t\tfor (const room of rooms) {\n\t\t\tthis.joinRoom(room);\n\t\t}\n\t\treturn this.rooms.bulk;\n\t}\n\n\t#leaveRooms(rooms: string[]): typeof this.rooms.bulk {\n\t\tif (!this.canSend) {\n\t\t\treturn this.rooms.bulk;\n\t\t}\n\t\tfor (const room of rooms) {\n\t\t\tthis.leaveRoom(room);\n\t\t}\n\t\treturn this.rooms.bulk;\n\t}\n\n\tprotected _close(): void {\n\t\tthis.#closed = true;\n\t\tthis.#clearAuthTimer();\n\t\tthis.clearHeartbeat();\n\t}\n\n\t_handleAuth<D>(\n\t\tparsed: { type: LifecycleTypes.auth; data: D } | null,\n\t\tauth: AuthFunction<TEvents, SD, D> | undefined,\n\t\tauthTimeout: number,\n\t\tnext: MiddlewareNext,\n\t) {\n\t\tif (auth && parsed !== null) {\n\t\t\tif (this.#authState !== AuthState.idle) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.#authState = AuthState.pending;\n\t\t\tthis.#authTimer = setTimeout(() => {\n\t\t\t\tif (!this.isClosed && !this.isAuthenticated) {\n\t\t\t\t\tconst err = new Error(\"Auth timeout\");\n\t\t\t\t\tthis.#setAuthFailed({ phase: \"auth\", error: err, code: 4008 });\n\t\t\t\t\tnext(err);\n\t\t\t\t}\n\t\t\t}, authTimeout);\n\t\t\ttry {\n\t\t\t\tauth(this, parsed.data, (payload, error) => {\n\t\t\t\t\tif (error) {\n\t\t\t\t\t\tconst err = error || new Error(\"Auth failed\");\n\t\t\t\t\t\tthis.#setAuthFailed({ phase: \"auth\", error: err, code: 4003 });\n\t\t\t\t\t\tnext(err);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tthis.#setAuthSuccess(payload);\n\t\t\t\t\tthis.rooms.join(this.broadcastRoom);\n\t\t\t\t\tthis.startHeartbeat();\n\t\t\t\t\tnext();\n\t\t\t\t});\n\t\t\t} catch (err) {\n\t\t\t\tthis.#setAuthFailed({ phase: \"auth\", error: err, code: 4003 });\n\t\t\t\tnext(err);\n\t\t\t}\n\t\t} else {\n\t\t\tthis.#handleNoAuth();\n\t\t\tthis.startHeartbeat();\n\t\t\tnext();\n\t\t}\n\t}\n\n\t#handleNoAuth() {\n\t\tif (this.#closed || this.#authState !== AuthState.idle) {\n\t\t\treturn;\n\t\t}\n\t\tthis.#authState = AuthState.none;\n\t\tthis.rooms.join(this.broadcastRoom);\n\t}\n\n\t#setAuthSuccess<P>(payload: P): void {\n\t\tif (this.#closed || this.#authState !== AuthState.pending) {\n\t\t\treturn;\n\t\t}\n\t\tthis.#clearAuthTimer();\n\t\tthis.#authState = AuthState.success;\n\t\tthis.payload = payload;\n\t\tthis.#sendUnchecked({ type: LifecycleTypes.auth_success });\n\t}\n\n\t#setAuthFailed(ctx: ErrorContext): void {\n\t\tif (this.#closed || this.#authState !== AuthState.pending) {\n\t\t\treturn;\n\t\t}\n\t\tthis.#clearAuthTimer();\n\t\tthis.#authState = AuthState.failed;\n\t\tthis.#sendUnchecked({ type: LifecycleTypes.auth_error, data: ctx });\n\t\tthis.close(ctx.code, ctx.phase);\n\t}\n\n\t#clearAuthTimer(): void {\n\t\tif (this.#authTimer) {\n\t\t\tclearTimeout(this.#authTimer);\n\t\t\tthis.#authTimer = null;\n\t\t}\n\t}\n}\n","// packages/server/src/byte-socket-server-base.ts\nimport {\n\tByteSocketBase,\n\tLifecycleTypes,\n\ttype AnyCallback,\n\ttype ErrorContext,\n\ttype EventsForRooms,\n\ttype SocketEvents,\n\ttype StringKeys,\n\ttype StringNumberKeys,\n\ttype UserMessage,\n} from \"@bytesocket/core\";\nimport type { IByteSocket, ILifecycleServer, IRoomsBulkLifecycleServer, IRoomsLifecycleServer, IRoomsServer, ISocket } from \"./interfaces\";\nimport { SocketServerBase } from \"./socket-server-base\";\nimport type {\n\tByteSocketOptionsBase,\n\tEventCallback,\n\tMiddleware,\n\tMiddlewareNext,\n\tRoomEventMiddleware,\n\tServerIncomingData,\n\tServerOutgoingData,\n\tSocketData,\n} from \"./types\";\n\ntype RequiredOptions =\n\t| \"middlewareTimeout\"\n\t| \"roomMiddlewareTimeout\"\n\t| \"authTimeout\"\n\t| \"broadcastRoom\"\n\t| \"onMiddlewareError\"\n\t| \"onMiddlewareTimeout\"\n\t| \"idleTimeout\"\n\t| \"sendPingsAutomatically\";\n\nexport abstract class ByteSocketServerBase<\n\tTEvents extends SocketEvents = SocketEvents,\n\tSD extends SocketData = SocketData,\n\tUpgradeCallback extends AnyCallback = AnyCallback,\n>\n\textends ByteSocketBase\n\timplements IByteSocket<TEvents, SD, UpgradeCallback>\n{\n\t// ──── Namespaces ────────────────────────────────────────────────────────────────────────\n\treadonly lifecycle: ILifecycleServer<TEvents, SD, UpgradeCallback>;\n\treadonly rooms: IRoomsServer<TEvents, SD>;\n\treadonly sockets = new Map<string, ISocket<TEvents, SD>>();\n\n\t// ──── States ────────────────────────────────────────────────────────────────────────\n\n\tprotected options: Omit<ByteSocketOptionsBase<TEvents, SD>, RequiredOptions | \"debug\" | \"serialization\" | \"msgpackrOptions\"> &\n\t\tPick<Required<ByteSocketOptionsBase<TEvents, SD>>, RequiredOptions>;\n\t#middlewares: Middleware<TEvents, SD>[] = [];\n\t#destroyed = false;\n\n\tconstructor(options: ByteSocketOptionsBase<TEvents, SD> = {}) {\n\t\tsuper(options);\n\n\t\tthis.options = {\n\t\t\t...options,\n\t\t\tmiddlewareTimeout: options.middlewareTimeout ?? 5000,\n\t\t\troomMiddlewareTimeout: options.roomMiddlewareTimeout ?? 5000,\n\t\t\tauthTimeout: options.authTimeout ?? 5000,\n\t\t\tbroadcastRoom: options.broadcastRoom ?? \"__bytesocket_broadcast__\",\n\t\t\tonMiddlewareError: options.onMiddlewareError ?? \"ignore\",\n\t\t\tonMiddlewareTimeout: options.onMiddlewareTimeout ?? \"ignore\",\n\t\t\tidleTimeout: options.idleTimeout ?? 120,\n\t\t\tsendPingsAutomatically: options.sendPingsAutomatically ?? true,\n\t\t};\n\n\t\tconst lifecycle: ILifecycleServer<TEvents, SD, UpgradeCallback> = {\n\t\t\tonUpgrade: (callback) => {\n\t\t\t\tthis._onLifecycle(LifecycleTypes.upgrade, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\toffUpgrade: (callback) => {\n\t\t\t\tthis._offLifecycle(LifecycleTypes.upgrade, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\tonceUpgrade: (callback) => {\n\t\t\t\tthis._onceLifecycle(LifecycleTypes.upgrade, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\n\t\t\tonOpen: (callback) => {\n\t\t\t\tthis._onLifecycle(LifecycleTypes.open, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\toffOpen: (callback) => {\n\t\t\t\tthis._offLifecycle(LifecycleTypes.open, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\tonceOpen: (callback) => {\n\t\t\t\tthis._onceLifecycle(LifecycleTypes.open, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\n\t\t\tonAuthSuccess: (callback) => {\n\t\t\t\tthis._onLifecycle(LifecycleTypes.auth_success, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\toffAuthSuccess: (callback) => {\n\t\t\t\tthis._offLifecycle(LifecycleTypes.auth_success, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\tonceAuthSuccess: (callback) => {\n\t\t\t\tthis._onceLifecycle(LifecycleTypes.auth_success, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\n\t\t\tonAuthError: (callback) => {\n\t\t\t\tthis._onLifecycle(LifecycleTypes.auth_error, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\toffAuthError: (callback) => {\n\t\t\t\tthis._offLifecycle(LifecycleTypes.auth_error, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\tonceAuthError: (callback) => {\n\t\t\t\tthis._onceLifecycle(LifecycleTypes.auth_error, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\n\t\t\tonMessage: (callback) => {\n\t\t\t\tthis._onLifecycle(LifecycleTypes.message, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\toffMessage: (callback) => {\n\t\t\t\tthis._offLifecycle(LifecycleTypes.message, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\tonceMessage: (callback) => {\n\t\t\t\tthis._onceLifecycle(LifecycleTypes.message, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\n\t\t\tonClose: (callback) => {\n\t\t\t\tthis._onLifecycle(LifecycleTypes.close, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\toffClose: (callback) => {\n\t\t\t\tthis._offLifecycle(LifecycleTypes.close, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\tonceClose: (callback) => {\n\t\t\t\tthis._onceLifecycle(LifecycleTypes.close, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\n\t\t\tonError: (callback) => {\n\t\t\t\tthis._onLifecycle(LifecycleTypes.error, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\toffError: (callback) => {\n\t\t\t\tthis._offLifecycle(LifecycleTypes.error, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\tonceError: (callback) => {\n\t\t\t\tthis._onceLifecycle(LifecycleTypes.error, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t};\n\n\t\tthis.lifecycle = lifecycle;\n\n\t\tconst roomsLifecycle: IRoomsLifecycleServer<TEvents, SD> = {\n\t\t\tonJoin: (callback) => {\n\t\t\t\tthis._onLifecycle(LifecycleTypes.join_room, callback);\n\t\t\t\treturn roomsLifecycle;\n\t\t\t},\n\t\t\toffJoin: (callback) => {\n\t\t\t\tthis._offLifecycle(LifecycleTypes.join_room, callback);\n\t\t\t\treturn roomsLifecycle;\n\t\t\t},\n\t\t\tonceJoin: (callback) => {\n\t\t\t\tthis._onceLifecycle(LifecycleTypes.join_room, callback);\n\t\t\t\treturn roomsLifecycle;\n\t\t\t},\n\n\t\t\tonLeave: (callback) => {\n\t\t\t\tthis._onLifecycle(LifecycleTypes.leave_room, callback);\n\t\t\t\treturn roomsLifecycle;\n\t\t\t},\n\t\t\toffLeave: (callback) => {\n\t\t\t\tthis._offLifecycle(LifecycleTypes.leave_room, callback);\n\t\t\t\treturn roomsLifecycle;\n\t\t\t},\n\t\t\tonceLeave: (callback) => {\n\t\t\t\tthis._onceLifecycle(LifecycleTypes.leave_room, callback);\n\t\t\t\treturn roomsLifecycle;\n\t\t\t},\n\t\t};\n\n\t\tconst roomsBulkLifecycle: IRoomsBulkLifecycleServer<TEvents, SD> = {\n\t\t\tonJoin: (callback) => {\n\t\t\t\tthis._onLifecycle(LifecycleTypes.join_rooms, callback);\n\t\t\t\treturn roomsBulkLifecycle;\n\t\t\t},\n\t\t\toffJoin: (callback) => {\n\t\t\t\tthis._offLifecycle(LifecycleTypes.join_rooms, callback);\n\t\t\t\treturn roomsBulkLifecycle;\n\t\t\t},\n\t\t\tonceJoin: (callback) => {\n\t\t\t\tthis._onceLifecycle(LifecycleTypes.join_rooms, callback);\n\t\t\t\treturn roomsBulkLifecycle;\n\t\t\t},\n\n\t\t\tonLeave: (callback) => {\n\t\t\t\tthis._onLifecycle(LifecycleTypes.leave_rooms, callback);\n\t\t\t\treturn roomsBulkLifecycle;\n\t\t\t},\n\t\t\toffLeave: (callback) => {\n\t\t\t\tthis._offLifecycle(LifecycleTypes.leave_rooms, callback);\n\t\t\t\treturn roomsBulkLifecycle;\n\t\t\t},\n\t\t\tonceLeave: (callback) => {\n\t\t\t\tthis._onceLifecycle(LifecycleTypes.leave_rooms, callback);\n\t\t\t\treturn roomsBulkLifecycle;\n\t\t\t},\n\t\t};\n\n\t\tthis.rooms = {\n\t\t\tpublishRaw: this.publishRaw.bind(this),\n\t\t\temit: this.#publish.bind(this),\n\t\t\ton: this.#onRoom.bind(this),\n\t\t\toff: this.#offRoom.bind(this),\n\t\t\tonce: this.#onceRoom.bind(this),\n\t\t\tlifecycle: roomsLifecycle,\n\t\t\tbulk: {\n\t\t\t\temit: this.#publishMany.bind(this),\n\t\t\t\tlifecycle: roomsBulkLifecycle,\n\t\t\t},\n\t\t};\n\t}\n\n\tabstract attach(server: unknown, path: string): this;\n\tabstract destroy(): void;\n\n\tprotected abstract publishRaw(room: string, message: ServerOutgoingData, isBinary?: boolean, compress?: boolean): typeof this.rooms;\n\n\tprotected _destroy(): void {\n\t\tthis.#destroyed = true;\n\n\t\tfor (const socket of this.sockets.values()) {\n\t\t\tif (!socket.isClosed) {\n\t\t\t\tsocket.close(1001, \"server destroy\");\n\t\t\t}\n\t\t}\n\t\tthis.sockets.clear();\n\n\t\tthis._clearCallbacks();\n\t\tthis.#middlewares = [];\n\t}\n\n\temit<E extends StringNumberKeys<TEvents[\"emit\"]>, D extends NonNullable<TEvents[\"emit\"]>[E]>(event: E, data: D): this {\n\t\tif (this.#destroyed) {\n\t\t\treturn this;\n\t\t}\n\t\tconst message = this.encode({ event, data });\n\t\tthis.publishRaw(this.options.broadcastRoom, message);\n\t\treturn this;\n\t}\n\n\t#publish<\n\t\tR extends StringKeys<TEvents[\"emitRoom\"]>,\n\t\tE extends StringNumberKeys<NonNullable<TEvents[\"emitRoom\"]>[R]>,\n\t\tD extends NonNullable<TEvents[\"emitRoom\"]>[R][E],\n\t>(room: R, event: E, data: D): typeof this.rooms {\n\t\tif (this.#destroyed) {\n\t\t\treturn this.rooms;\n\t\t}\n\t\tconst message = this.encode({ room, event, data });\n\t\tthis.publishRaw(room, message);\n\t\treturn this.rooms;\n\t}\n\n\t#publishMany<\n\t\tRs extends NonNullable<TEvents[\"emitRooms\"]>[\"rooms\"],\n\t\tE extends StringNumberKeys<EventsForRooms<NonNullable<TEvents[\"emitRooms\"]>, Rs>>,\n\t\tD extends NonNullable<EventsForRooms<NonNullable<TEvents[\"emitRooms\"]>, Rs>>[E],\n\t>(rooms: Rs, event: E, data: D): typeof this.rooms.bulk {\n\t\tif (this.#destroyed) {\n\t\t\treturn this.rooms.bulk;\n\t\t}\n\t\tconst message = this.encode({ rooms, event, data });\n\t\tfor (const room of rooms) {\n\t\t\tthis.publishRaw(room, message);\n\t\t}\n\t\treturn this.rooms.bulk;\n\t}\n\n\ton<E extends StringNumberKeys<TEvents[\"listen\"]>, D extends NonNullable<TEvents[\"listen\"]>[E]>(\n\t\tevent: E,\n\t\tcallback: EventCallback<TEvents, SD, D>,\n\t): this {\n\t\tthis._on(event, callback);\n\t\treturn this;\n\t}\n\n\toff<E extends StringNumberKeys<TEvents[\"listen\"]>, D extends NonNullable<TEvents[\"listen\"]>[E]>(\n\t\tevent: E,\n\t\tcallback?: EventCallback<TEvents, SD, D>,\n\t): this {\n\t\tthis._off(event, callback);\n\t\treturn this;\n\t}\n\n\tonce<E extends StringNumberKeys<TEvents[\"listen\"]>, D extends NonNullable<TEvents[\"listen\"]>[E]>(\n\t\tevent: E,\n\t\tcallback: EventCallback<TEvents, SD, D>,\n\t): this {\n\t\tthis._once(event, callback);\n\t\treturn this;\n\t}\n\n\t#onRoom<\n\t\tR extends StringKeys<TEvents[\"listenRoom\"]>,\n\t\tE extends StringNumberKeys<NonNullable<TEvents[\"listenRoom\"]>[R]>,\n\t\tD extends NonNullable<TEvents[\"listenRoom\"]>[R][E],\n\t>(room: R, event: E, callback: RoomEventMiddleware<TEvents, SD, D>): typeof this.rooms {\n\t\tthis._onRoom(room, event, callback);\n\t\treturn this.rooms;\n\t}\n\n\t#offRoom<\n\t\tR extends StringKeys<TEvents[\"listenRoom\"]>,\n\t\tE extends StringNumberKeys<NonNullable<TEvents[\"listenRoom\"]>[R]>,\n\t\tD extends NonNullable<TEvents[\"listenRoom\"]>[R][E],\n\t>(room: R, event?: E, callback?: RoomEventMiddleware<TEvents, SD, D>): typeof this.rooms {\n\t\tthis._offRoom(room, event, callback);\n\t\treturn this.rooms;\n\t}\n\n\t#onceRoom<\n\t\tR extends StringKeys<TEvents[\"listenRoom\"]>,\n\t\tE extends StringNumberKeys<NonNullable<TEvents[\"listenRoom\"]>[R]>,\n\t\tD extends NonNullable<TEvents[\"listenRoom\"]>[R][E],\n\t>(room: R, event: E, callback: RoomEventMiddleware<TEvents, SD, D>): typeof this.rooms {\n\t\tthis._onceRoom(room, event, callback);\n\t\treturn this.rooms;\n\t}\n\n\tuse(fn: Middleware<TEvents, SD>): this {\n\t\tthis.#middlewares.push(fn);\n\t\treturn this;\n\t}\n\n\t#runMiddlewares<R extends string, E extends string | number, D>(\n\t\tsocket: ISocket<TEvents, SD>,\n\t\tctx: UserMessage<R, E, D>,\n\t\tfinalCallback: () => void,\n\t): void {\n\t\tlet index = 0;\n\t\tlet aborted = false;\n\n\t\tconst stack = Array.from(this.#middlewares);\n\n\t\tconst next: MiddlewareNext = (error) => {\n\t\t\tif (aborted) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (error) {\n\t\t\t\taborted = true;\n\t\t\t\tconst isTimeout = error instanceof Error && error.name === \"TimeoutError\";\n\t\t\t\tconst phase = isTimeout ? \"middlewareTimeout\" : \"middleware\";\n\t\t\t\tthis._triggerCallbacks(this._lifecycleCallbacksMap.get(LifecycleTypes.error), socket, { phase, error });\n\n\t\t\t\tconst option = isTimeout ? this.options.onMiddlewareTimeout : this.options.onMiddlewareError;\n\t\t\t\tif (option === \"close\") {\n\t\t\t\t\tsocket.close(1011, error instanceof Error ? error.message : String(error));\n\t\t\t\t} else if (typeof option === \"function\") {\n\t\t\t\t\toption(error, socket);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (index >= stack.length) {\n\t\t\t\ttry {\n\t\t\t\t\treturn finalCallback();\n\t\t\t\t} catch (err) {\n\t\t\t\t\tthis._triggerCallbacks(this._lifecycleCallbacksMap.get(LifecycleTypes.error), socket, { phase: \"finalCallback\", error: err });\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst middleware = stack[index++];\n\t\t\tlet called = false;\n\t\t\tlet timeoutId: ReturnType<typeof setTimeout> | null = null;\n\n\t\t\tconst execution = new Promise<void>((resolve, reject) => {\n\t\t\t\ttry {\n\t\t\t\t\tconst result = middleware(socket, ctx, (err) => {\n\t\t\t\t\t\tif (called) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcalled = true;\n\t\t\t\t\t\tif (err) {\n\t\t\t\t\t\t\treject(err);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tresolve();\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\n\t\t\t\t\tif (result instanceof Promise) {\n\t\t\t\t\t\tresult.then(\n\t\t\t\t\t\t\t() => {\n\t\t\t\t\t\t\t\tif (!called) {\n\t\t\t\t\t\t\t\t\tcalled = true;\n\t\t\t\t\t\t\t\t\tresolve();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t(err) => {\n\t\t\t\t\t\t\t\tif (!called) {\n\t\t\t\t\t\t\t\t\tcalled = true;\n\t\t\t\t\t\t\t\t\treject(err);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t} catch (syncErr) {\n\t\t\t\t\tif (!called) {\n\t\t\t\t\t\tcalled = true;\n\t\t\t\t\t\treject(syncErr);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tconst timeout = new Promise<void>((_, reject) => {\n\t\t\t\ttimeoutId = setTimeout(() => {\n\t\t\t\t\tif (!called) {\n\t\t\t\t\t\tcalled = true;\n\t\t\t\t\t\tconst timeoutError = new Error(`Middleware timeout after ${this.options.middlewareTimeout}ms`);\n\t\t\t\t\t\ttimeoutError.name = \"TimeoutError\";\n\t\t\t\t\t\treject(timeoutError);\n\t\t\t\t\t}\n\t\t\t\t}, this.options.middlewareTimeout);\n\t\t\t});\n\n\t\t\tPromise.race([execution, timeout])\n\t\t\t\t.then(() => next())\n\t\t\t\t.catch((err) => next(err))\n\t\t\t\t.finally(() => {\n\t\t\t\t\tif (timeoutId) {\n\t\t\t\t\t\tclearTimeout(timeoutId);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t};\n\n\t\tnext();\n\t}\n\n\tget destroyed(): boolean {\n\t\treturn this.#destroyed;\n\t}\n\n\t#rawMessageDescription(message: ServerIncomingData, isBinary: boolean): string {\n\t\tif (Array.isArray(message)) {\n\t\t\tconst total = message.reduce((s, b) => s + b.length, 0);\n\t\t\treturn `fragmented (${message.length} parts, ${total} bytes)`;\n\t\t}\n\t\tif (isBinary) {\n\t\t\tconst len = Buffer.isBuffer(message) ? message.length : message.byteLength;\n\t\t\treturn `binary (${len} bytes)`;\n\t\t}\n\t\treturn typeof message === \"string\" ? message : new TextDecoder().decode(message);\n\t}\n\n\tprotected message(socket: ISocket<TEvents, SD>, message: ServerIncomingData, isBinary: boolean) {\n\t\tthis._runSyncHooks(this._lifecycleCallbacksMap.get(LifecycleTypes.message), [socket, message, isBinary], (error) => {\n\t\t\tif (error != null) {\n\t\t\t\tthis._triggerCallbacks(this._lifecycleCallbacksMap.get(LifecycleTypes.error), socket, { phase: \"onMessage\", error });\n\t\t\t}\n\t\t});\n\n\t\tif (isBinary && (message.byteLength === 0 || (message instanceof Buffer && message.length === 0))) {\n\t\t\tsocket.sendRaw(new Uint8Array(0), true);\n\t\t\treturn;\n\t\t}\n\n\t\tlet parsed;\n\t\ttry {\n\t\t\tparsed = this.decode(message, isBinary);\n\t\t} catch (error) {\n\t\t\tconst raw = this.#rawMessageDescription(message, isBinary);\n\t\t\tthis._triggerCallbacks(this._lifecycleCallbacksMap.get(LifecycleTypes.error), socket, { phase: \"decode\", raw, error });\n\t\t\tsocket.close(1008, \"decode error\");\n\t\t\treturn;\n\t\t}\n\n\t\tif (parsed == null || typeof parsed !== \"object\") {\n\t\t\tconst error = new Error(\"Message must be an object\");\n\t\t\tthis._triggerCallbacks(this._lifecycleCallbacksMap.get(LifecycleTypes.error), socket, {\n\t\t\t\tphase: \"validation\",\n\t\t\t\traw: JSON.stringify(parsed),\n\t\t\t\terror,\n\t\t\t});\n\t\t\tsocket.close(1008, \"bad format\");\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.#handleAuthMessage(socket, parsed)) {\n\t\t\treturn;\n\t\t}\n\t\tif (!socket.isAuthenticated) {\n\t\t\treturn;\n\t\t}\n\t\tif (this.#handleJoinRoomMessage(socket, parsed)) {\n\t\t\treturn;\n\t\t}\n\t\tif (this.#handleLeaveRoomMessage(socket, parsed)) {\n\t\t\treturn;\n\t\t}\n\t\tif (this.#handleJoinRoomsMessage(socket, parsed)) {\n\t\t\treturn;\n\t\t}\n\t\tif (this.#handleLeaveRoomsMessage(socket, parsed)) {\n\t\t\treturn;\n\t\t}\n\t\tthis.#runMiddlewares(socket, parsed as UserMessage, () => {\n\t\t\tif (this.#handleRoomsEventMessage(socket, parsed)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (this.#handleRoomEventMessage(socket, parsed)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (this.#handleEventMessage(socket, parsed)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t});\n\t}\n\n\tprotected close(socket: ISocket<TEvents, SD>, code: number, reason: Buffer | ArrayBuffer) {\n\t\tif (this._debug && code === 4008) {\n\t\t\tconsole.warn(`Auth timeout for socket ${socket.id}`);\n\t\t}\n\t\tthis.sockets.delete(socket.id);\n\t\tsocket.close(code, Buffer.from(reason as ArrayBuffer).toString(\"utf8\"));\n\t\tthis._runSyncHooks(this._lifecycleCallbacksMap.get(LifecycleTypes.close), [socket, code, reason], (error) => {\n\t\t\tif (error != null) {\n\t\t\t\tthis._triggerCallbacks(this._lifecycleCallbacksMap.get(LifecycleTypes.error), socket, { phase: \"onClose\", error });\n\t\t\t}\n\t\t});\n\t}\n\n\t#handleAuthMessage<T extends object>(socket: ISocket<TEvents, SD>, parsed: T): boolean {\n\t\tif (!this._isLifecyclePayloadMessage(LifecycleTypes.auth, parsed)) {\n\t\t\treturn false;\n\t\t}\n\t\tsocket._handleAuth(parsed, this.options.auth, this.options.authTimeout, (err) => {\n\t\t\tif (err == null) {\n\t\t\t\tthis._runSyncHooks(this._lifecycleCallbacksMap.get(LifecycleTypes.auth_success), [socket], (error) => {\n\t\t\t\t\tif (error != null) {\n\t\t\t\t\t\tthis._triggerCallbacks(this._lifecycleCallbacksMap.get(LifecycleTypes.error), socket, { phase: \"onAuthSuccess\", error });\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tthis._runSyncHooks(this._lifecycleCallbacksMap.get(LifecycleTypes.open), [socket], (error) => {\n\t\t\t\t\tif (error != null) {\n\t\t\t\t\t\tthis._triggerCallbacks(this._lifecycleCallbacksMap.get(LifecycleTypes.error), socket, { phase: \"onOpen\", error });\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tconst ctx: ErrorContext = {\n\t\t\t\t\tphase: \"auth\",\n\t\t\t\t\terror: err instanceof Error ? err : new Error(String(err)),\n\t\t\t\t\tcode: 4003,\n\t\t\t\t};\n\t\t\t\tthis._runSyncHooks(this._lifecycleCallbacksMap.get(LifecycleTypes.auth_error), [socket, ctx], (error) => {\n\t\t\t\t\tif (error != null) {\n\t\t\t\t\t\tthis._triggerCallbacks(this._lifecycleCallbacksMap.get(LifecycleTypes.error), socket, { phase: \"onAuthError\", error });\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\t\treturn true;\n\t}\n\n\t#handleJoinRoomMessage<T extends object>(socket: ISocket<TEvents, SD>, parsed: T): boolean {\n\t\tif (!this._isLifecycleRoomMessage(LifecycleTypes.join_room, parsed)) {\n\t\t\treturn false;\n\t\t}\n\t\tthis.#runAsyncHooksOrNext(this._lifecycleCallbacksMap.get(LifecycleTypes.join_room), [socket, parsed.room], (error) => {\n\t\t\tif (error == null) {\n\t\t\t\tsocket.rooms.join(parsed.room);\n\t\t\t\tsocket.send({ type: LifecycleTypes.join_room_success, room: parsed.room });\n\t\t\t} else {\n\t\t\t\tsocket.send({ type: LifecycleTypes.join_room_error, room: parsed.room, data: { phase: \"onJoinRoom\", error } });\n\t\t\t}\n\t\t});\n\t\treturn true;\n\t}\n\n\t#handleLeaveRoomMessage<T extends object>(socket: ISocket<TEvents, SD>, parsed: T): boolean {\n\t\tif (!this._isLifecycleRoomMessage(LifecycleTypes.leave_room, parsed)) {\n\t\t\treturn false;\n\t\t}\n\t\tthis.#runAsyncHooksOrNext(this._lifecycleCallbacksMap.get(LifecycleTypes.leave_room), [socket, parsed.room], (error) => {\n\t\t\tif (error == null) {\n\t\t\t\tsocket.rooms.leave(parsed.room);\n\t\t\t\tsocket.send({ type: LifecycleTypes.leave_room_success, room: parsed.room });\n\t\t\t} else {\n\t\t\t\tsocket.send({ type: LifecycleTypes.leave_room_error, room: parsed.room, data: { phase: \"onLeaveRoom\", error } });\n\t\t\t}\n\t\t});\n\t\treturn true;\n\t}\n\n\t#handleJoinRoomsMessage<T extends object>(socket: ISocket<TEvents, SD>, parsed: T): boolean {\n\t\tif (!this._isLifecycleRoomsMessage(LifecycleTypes.join_rooms, parsed)) {\n\t\t\treturn false;\n\t\t}\n\t\tthis.#runAsyncHooksOrNext(this._lifecycleCallbacksMap.get(LifecycleTypes.join_rooms), [socket, parsed.rooms], (error) => {\n\t\t\tif (error == null) {\n\t\t\t\tsocket.rooms.bulk.join(parsed.rooms);\n\t\t\t\tsocket.send({ type: LifecycleTypes.join_rooms_success, rooms: parsed.rooms });\n\t\t\t} else {\n\t\t\t\tsocket.send({ type: LifecycleTypes.join_rooms_error, rooms: parsed.rooms, data: { phase: \"onJoinRooms\", error } });\n\t\t\t}\n\t\t});\n\t\treturn true;\n\t}\n\n\t#handleLeaveRoomsMessage<T extends object>(socket: ISocket<TEvents, SD>, parsed: T): boolean {\n\t\tif (!this._isLifecycleRoomsMessage(LifecycleTypes.leave_rooms, parsed)) {\n\t\t\treturn false;\n\t\t}\n\t\tthis.#runAsyncHooksOrNext(this._lifecycleCallbacksMap.get(LifecycleTypes.leave_rooms), [socket, parsed.rooms], (error) => {\n\t\t\tif (error == null) {\n\t\t\t\tsocket.rooms.bulk.leave(parsed.rooms);\n\t\t\t\tsocket.send({ type: LifecycleTypes.leave_rooms_success, rooms: parsed.rooms });\n\t\t\t} else {\n\t\t\t\tsocket.send({ type: LifecycleTypes.leave_rooms_error, rooms: parsed.rooms, data: { phase: \"onLeaveRooms\", error } });\n\t\t\t}\n\t\t});\n\t\treturn true;\n\t}\n\n\t#handleRoomsEventMessage<T extends object>(socket: ISocket<TEvents, SD>, parsed: T): boolean {\n\t\tif (!this._isRoomsEventMessage(parsed)) {\n\t\t\treturn false;\n\t\t}\n\t\tconst message = this.encode({ rooms: parsed.rooms, event: parsed.event, data: parsed.data });\n\t\tfor (const room of parsed.rooms) {\n\t\t\tthis.#runAsyncHooksOrNext(this._roomCallbacksMap.get(room)?.get(parsed.event), [socket, parsed.data], (error) => {\n\t\t\t\tif (error == null) {\n\t\t\t\t\tsocket.rooms.publishRaw(room, message);\n\t\t\t\t} else {\n\t\t\t\t\tthis._triggerCallbacks(this._lifecycleCallbacksMap.get(LifecycleTypes.error), socket, {\n\t\t\t\t\t\tphase: \"rooms message\",\n\t\t\t\t\t\traw: JSON.stringify(parsed),\n\t\t\t\t\t\terror,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\treturn true;\n\t}\n\n\t#handleRoomEventMessage<T extends object>(socket: ISocket<TEvents, SD>, parsed: T): boolean {\n\t\tif (!this._isRoomEventMessage(parsed)) {\n\t\t\treturn false;\n\t\t}\n\t\tthis.#runAsyncHooksOrNext(this._roomCallbacksMap.get(parsed.room)?.get(parsed.event), [socket, parsed.data], (error) => {\n\t\t\tif (error == null) {\n\t\t\t\tconst message = this.encode({ room: parsed.room, event: parsed.event, data: parsed.data });\n\t\t\t\tsocket.rooms.publishRaw(parsed.room, message);\n\t\t\t} else {\n\t\t\t\tthis._triggerCallbacks(this._lifecycleCallbacksMap.get(LifecycleTypes.error), socket, {\n\t\t\t\t\tphase: \"room message\",\n\t\t\t\t\traw: JSON.stringify(parsed),\n\t\t\t\t\terror,\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\t\treturn true;\n\t}\n\n\t#handleEventMessage<T extends object>(socket: ISocket<TEvents, SD>, parsed: T): boolean {\n\t\tif (!this._isEventMessage(parsed)) {\n\t\t\treturn false;\n\t\t}\n\t\tthis._triggerCallbacks(this._callbacksMap.get(parsed.event), socket, parsed.data);\n\t\treturn true;\n\t}\n\n\tprotected _runSyncHooks<Args extends Array<unknown>>(callbackSet: Set<AnyCallback> | undefined, args: Args, next: MiddlewareNext): void {\n\t\tif (!callbackSet) {\n\t\t\treturn next();\n\t\t}\n\t\tlet firstError: unknown = null;\n\t\tfor (const callback of callbackSet) {\n\t\t\ttry {\n\t\t\t\tcallback(...args);\n\t\t\t} catch (err) {\n\t\t\t\tif (this._debug) {\n\t\t\t\t\tconsole.error(err);\n\t\t\t\t}\n\t\t\t\tfirstError = firstError ?? err;\n\t\t\t}\n\t\t}\n\t\tnext(firstError);\n\t}\n\n\t#runAsyncHooksOrNext<Args extends Array<unknown>>(callbacks: Set<AnyCallback> | undefined, args: Args, finalCallback: MiddlewareNext): void {\n\t\tif (!callbacks || callbacks.size === 0) {\n\t\t\ttry {\n\t\t\t\tfinalCallback();\n\t\t\t} catch (err) {\n\t\t\t\tconst socket = args[0] instanceof SocketServerBase ? args[0] : undefined;\n\t\t\t\tthis._triggerCallbacks(this._lifecycleCallbacksMap.get(LifecycleTypes.error), socket, { phase: \"asyncHookFinal\", error: err });\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tconst stack = Array.from(callbacks);\n\t\tlet index = 0;\n\n\t\tconst next: MiddlewareNext = (error) => {\n\t\t\tif (error) {\n\t\t\t\treturn finalCallback(error);\n\t\t\t}\n\t\t\tif (index >= stack.length) {\n\t\t\t\ttry {\n\t\t\t\t\treturn finalCallback();\n\t\t\t\t} catch (err) {\n\t\t\t\t\tconst socket = args[0] instanceof SocketServerBase ? args[0] : undefined;\n\t\t\t\t\tthis._triggerCallbacks(this._lifecycleCallbacksMap.get(LifecycleTypes.error), socket, { phase: \"asyncHookFinal\", error: err });\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst callback = stack[index++];\n\t\t\tlet called = false;\n\t\t\tlet timeoutId: ReturnType<typeof setTimeout> | null = null;\n\n\t\t\tconst execution = new Promise<void>((resolve, reject) => {\n\t\t\t\ttry {\n\t\t\t\t\tconst result = callback(...args, (err?: unknown) => {\n\t\t\t\t\t\tif (called) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcalled = true;\n\t\t\t\t\t\tif (err) {\n\t\t\t\t\t\t\treject(err);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tresolve();\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\n\t\t\t\t\tif (result instanceof Promise) {\n\t\t\t\t\t\tresult.then(\n\t\t\t\t\t\t\t() => {\n\t\t\t\t\t\t\t\tif (!called) {\n\t\t\t\t\t\t\t\t\tcalled = true;\n\t\t\t\t\t\t\t\t\tresolve();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t(err) => {\n\t\t\t\t\t\t\t\tif (!called) {\n\t\t\t\t\t\t\t\t\tcalled = true;\n\t\t\t\t\t\t\t\t\treject(err);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t} catch (syncErr) {\n\t\t\t\t\tif (!called) {\n\t\t\t\t\t\tcalled = true;\n\t\t\t\t\t\treject(syncErr);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tconst timeout = new Promise<void>((_, reject) => {\n\t\t\t\ttimeoutId = setTimeout(() => {\n\t\t\t\t\tif (!called) {\n\t\t\t\t\t\tcalled = true;\n\t\t\t\t\t\tconst timeoutError = new Error(`Room middleware timeout after ${this.options.roomMiddlewareTimeout}ms`);\n\t\t\t\t\t\ttimeoutError.name = \"TimeoutError\";\n\t\t\t\t\t\treject(timeoutError);\n\t\t\t\t\t}\n\t\t\t\t}, this.options.roomMiddlewareTimeout);\n\t\t\t});\n\n\t\t\tPromise.race([execution, timeout])\n\t\t\t\t.then(() => next())\n\t\t\t\t.catch((err) => next(err))\n\t\t\t\t.finally(() => {\n\t\t\t\t\tif (timeoutId) {\n\t\t\t\t\t\tclearTimeout(timeoutId);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t};\n\n\t\tnext();\n\t}\n}\n"],"mappings":"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"}
{"version":3,"file":"index.cjs","names":["AuthState","#authState","#closed","#encode","#publish","#publishMany","#joinRooms","#leaveRooms","#clearAuthTimer","#authTimer","#setAuthFailed","#setAuthSuccess","#handleNoAuth","#sendUnchecked","LifecycleTypes","ByteSocketBase","LifecycleTypes","#publish","#onRoom","#offRoom","#onceRoom","#publishMany","#destroyed","#middlewares","#isPromiseLike","#rawMessageDescription","#handleAuthMessage","#handleJoinRoomMessage","#handleLeaveRoomMessage","#handleJoinRoomsMessage","#handleLeaveRoomsMessage","#runMiddlewares","#handleRoomsEventMessage","#handleRoomEventMessage","#handleEventMessage","#runAsyncHooksOrNext"],"sources":["../src/socket-server-base.ts","../src/byte-socket-server-base.ts"],"sourcesContent":["// packages/server/src/socket-server-base.ts\nimport {\n\tAuthState,\n\tLifecycleTypes,\n\ttype ErrorContext,\n\ttype EventsForRooms,\n\ttype LifecycleMessage,\n\ttype SocketEvents,\n\ttype StringKeys,\n\ttype StringNumberKeys,\n\ttype UserMessage,\n} from \"@bytesocket/core\";\nimport type { ISocket, ISocketRooms } from \"./interfaces\";\nimport type { AuthFunction, MiddlewareNext, ServerOutgoingData, SocketData } from \"./types\";\n\nexport abstract class SocketServerBase<TEvents extends SocketEvents = SocketEvents, SD extends SocketData = SocketData> implements ISocket<\n\tTEvents,\n\tSD\n> {\n\treadonly rooms: ISocketRooms<TEvents>;\n\n\tpayload: any = {};\n\tlocals: any = {};\n\n\t#encode: <R extends string, E extends string | number, D>(\n\t\tpayload: LifecycleMessage<R, D> | UserMessage<R, E, D>,\n\t) => string | Buffer<ArrayBufferLike>;\n\t#authState: AuthState = AuthState.idle;\n\t#authTimer: ReturnType<typeof setTimeout> | null = null;\n\t#closed: boolean = false;\n\n\tget isAuthenticated(): boolean {\n\t\treturn this.#authState === AuthState.none || this.#authState === AuthState.success;\n\t}\n\tget isClosed(): boolean {\n\t\treturn this.#closed;\n\t}\n\tget canSend(): boolean {\n\t\treturn !this.#closed && this.isAuthenticated;\n\t}\n\n\tabstract readonly userData: SD;\n\tget id(): string {\n\t\treturn this.userData.socketKey;\n\t}\n\tget url(): string {\n\t\treturn this.userData.url;\n\t}\n\tget query(): string {\n\t\treturn this.userData.query;\n\t}\n\tget cookie(): string {\n\t\treturn this.userData.cookie;\n\t}\n\tget authorization(): string {\n\t\treturn this.userData.authorization;\n\t}\n\tget userAgent(): string {\n\t\treturn this.userData.userAgent;\n\t}\n\tget host(): string {\n\t\treturn this.userData.host;\n\t}\n\tget xForwardedFor(): string {\n\t\treturn this.userData.xForwardedFor;\n\t}\n\n\tprotected abstract readonly broadcastRoom: string;\n\n\tconstructor(\n\t\tencode: <R extends string, E extends string | number, D>(\n\t\t\tpayload: LifecycleMessage<R, D> | UserMessage<R, E, D>,\n\t\t) => string | Buffer<ArrayBufferLike>,\n\t) {\n\t\tthis.#encode = encode;\n\t\tthis.rooms = {\n\t\t\tpublishRaw: this.publishRaw.bind(this),\n\t\t\temit: this.#publish.bind(this),\n\t\t\tjoin: this.joinRoom.bind(this),\n\t\t\tleave: this.leaveRoom.bind(this),\n\t\t\tlist: this.getRoomList.bind(this),\n\t\t\tbulk: {\n\t\t\t\temit: this.#publishMany.bind(this),\n\t\t\t\tjoin: this.#joinRooms.bind(this),\n\t\t\t\tleave: this.#leaveRooms.bind(this),\n\t\t\t},\n\t\t};\n\t}\n\n\tabstract sendRaw(message: ServerOutgoingData, isBinary?: boolean, compress?: boolean): this;\n\n\tprotected abstract getRoomList(includeBroadcast?: boolean): string[];\n\n\tprotected abstract publishRaw(room: string, message: ServerOutgoingData, isBinary?: boolean, compress?: boolean): typeof this.rooms;\n\n\tprotected abstract joinRoom(room: string): typeof this.rooms;\n\n\tprotected abstract leaveRoom(room: string): typeof this.rooms;\n\n\tabstract close(code?: number, reason?: string): void;\n\n\tprotected startHeartbeat(): void {}\n\n\tprotected clearHeartbeat(): void {}\n\n\temit<E extends StringNumberKeys<TEvents[\"emit\"]>, D extends NonNullable<TEvents[\"emit\"]>[E]>(event: E, data: D): this {\n\t\tthis.send({ event, data });\n\t\treturn this;\n\t}\n\n\tsend<R extends string, E extends string | number, D>(payload: LifecycleMessage<R, D> | UserMessage<R, E, D>): this {\n\t\tif (!this.canSend) {\n\t\t\treturn this;\n\t\t}\n\t\tconst message = this.#encode(payload);\n\t\tthis.sendRaw(message);\n\t\treturn this;\n\t}\n\n\tbroadcast<E extends StringNumberKeys<TEvents[\"emit\"]>, D extends NonNullable<TEvents[\"emit\"]>[E]>(event: E, data: D): this {\n\t\tif (!this.canSend) {\n\t\t\treturn this;\n\t\t}\n\t\tconst message = this.#encode({ event, data });\n\t\tthis.publishRaw(this.broadcastRoom, message);\n\t\treturn this;\n\t}\n\n\t#sendUnchecked<R extends string, E extends string | number, D>(payload: LifecycleMessage<R, D> | UserMessage<R, E, D>): void {\n\t\tif (this.#closed) {\n\t\t\treturn;\n\t\t}\n\t\tconst message = this.#encode(payload);\n\t\tthis.sendRaw(message);\n\t}\n\n\t#publish<\n\t\tR extends StringKeys<TEvents[\"emitRoom\"]>,\n\t\tE extends StringNumberKeys<NonNullable<TEvents[\"emitRoom\"]>[R]>,\n\t\tD extends NonNullable<TEvents[\"emitRoom\"]>[R][E],\n\t>(room: R, event: E, data: D): typeof this.rooms {\n\t\tif (!this.canSend) {\n\t\t\treturn this.rooms;\n\t\t}\n\t\tconst message = this.#encode({ room, event, data });\n\t\tthis.publishRaw(room, message);\n\t\treturn this.rooms;\n\t}\n\n\t#publishMany<\n\t\tRs extends NonNullable<TEvents[\"emitRooms\"]>[\"rooms\"],\n\t\tE extends StringNumberKeys<EventsForRooms<NonNullable<TEvents[\"emitRooms\"]>, Rs>>,\n\t\tD extends NonNullable<EventsForRooms<NonNullable<TEvents[\"emitRooms\"]>, Rs>>[E],\n\t>(rooms: Rs, event: E, data: D): typeof this.rooms.bulk {\n\t\tif (!this.canSend) {\n\t\t\treturn this.rooms.bulk;\n\t\t}\n\t\tconst message = this.#encode({ rooms, event, data });\n\t\tfor (const room of rooms) {\n\t\t\tthis.publishRaw(room, message);\n\t\t}\n\t\treturn this.rooms.bulk;\n\t}\n\n\t#joinRooms(rooms: string[]): typeof this.rooms.bulk {\n\t\tif (!this.canSend) {\n\t\t\treturn this.rooms.bulk;\n\t\t}\n\t\tfor (const room of rooms) {\n\t\t\tthis.joinRoom(room);\n\t\t}\n\t\treturn this.rooms.bulk;\n\t}\n\n\t#leaveRooms(rooms: string[]): typeof this.rooms.bulk {\n\t\tif (!this.canSend) {\n\t\t\treturn this.rooms.bulk;\n\t\t}\n\t\tfor (const room of rooms) {\n\t\t\tthis.leaveRoom(room);\n\t\t}\n\t\treturn this.rooms.bulk;\n\t}\n\n\tprotected _close(): void {\n\t\tthis.#closed = true;\n\t\tthis.#clearAuthTimer();\n\t\tthis.clearHeartbeat();\n\t}\n\n\t_handleAuth<D>(\n\t\tparsed: { type: LifecycleTypes.auth; data: D } | null,\n\t\tauth: AuthFunction<TEvents, SD, D> | undefined,\n\t\tauthTimeout: number,\n\t\tnext: MiddlewareNext,\n\t) {\n\t\tif (auth && parsed !== null) {\n\t\t\tif (this.#authState !== AuthState.idle) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.#authState = AuthState.pending;\n\t\t\tif (authTimeout > 0) {\n\t\t\t\tthis.#authTimer = setTimeout(() => {\n\t\t\t\t\tif (!this.isClosed && !this.isAuthenticated) {\n\t\t\t\t\t\tconst err = new Error(\"Auth timeout\");\n\t\t\t\t\t\tthis.#setAuthFailed({ phase: \"auth\", error: err, code: 4008 });\n\t\t\t\t\t\tnext(err);\n\t\t\t\t\t}\n\t\t\t\t}, authTimeout);\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tauth(this, parsed.data, (payload, error) => {\n\t\t\t\t\tif (error) {\n\t\t\t\t\t\tconst err = error || new Error(\"Auth failed\");\n\t\t\t\t\t\tthis.#setAuthFailed({ phase: \"auth\", error: err, code: 4003 });\n\t\t\t\t\t\tnext(err);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tthis.#setAuthSuccess(payload);\n\t\t\t\t\tthis.rooms.join(this.broadcastRoom);\n\t\t\t\t\tthis.startHeartbeat();\n\t\t\t\t\tnext();\n\t\t\t\t});\n\t\t\t} catch (err) {\n\t\t\t\tthis.#setAuthFailed({ phase: \"auth\", error: err, code: 4003 });\n\t\t\t\tnext(err);\n\t\t\t}\n\t\t} else {\n\t\t\tthis.#handleNoAuth();\n\t\t\tthis.startHeartbeat();\n\t\t\tnext();\n\t\t}\n\t}\n\n\t#handleNoAuth() {\n\t\tif (this.#closed || this.#authState !== AuthState.idle) {\n\t\t\treturn;\n\t\t}\n\t\tthis.#authState = AuthState.none;\n\t\tthis.rooms.join(this.broadcastRoom);\n\t}\n\n\t#setAuthSuccess<P>(payload: P): void {\n\t\tif (this.#closed || this.#authState !== AuthState.pending) {\n\t\t\treturn;\n\t\t}\n\t\tthis.#clearAuthTimer();\n\t\tthis.#authState = AuthState.success;\n\t\tthis.payload = payload;\n\t\tthis.#sendUnchecked({ type: LifecycleTypes.auth_success });\n\t}\n\n\t#setAuthFailed(ctx: ErrorContext): void {\n\t\tif (this.#closed || this.#authState !== AuthState.pending) {\n\t\t\treturn;\n\t\t}\n\t\tthis.#clearAuthTimer();\n\t\tthis.#authState = AuthState.failed;\n\t\tthis.#sendUnchecked({ type: LifecycleTypes.auth_error, data: ctx });\n\t\tthis.close(ctx.code, ctx.phase);\n\t}\n\n\t#clearAuthTimer(): void {\n\t\tif (this.#authTimer) {\n\t\t\tclearTimeout(this.#authTimer);\n\t\t\tthis.#authTimer = null;\n\t\t}\n\t}\n}\n","// packages/server/src/byte-socket-server-base.ts\nimport {\n\tByteSocketBase,\n\tLifecycleTypes,\n\ttype AnyCallback,\n\ttype ErrorContext,\n\ttype EventsForRooms,\n\ttype SocketEvents,\n\ttype StringKeys,\n\ttype StringNumberKeys,\n\ttype UserMessage,\n} from \"@bytesocket/core\";\nimport type { IByteSocket, ILifecycleServer, IRoomsBulkLifecycleServer, IRoomsLifecycleServer, IRoomsServer, ISocket } from \"./interfaces\";\nimport { SocketServerBase } from \"./socket-server-base\";\nimport type {\n\tByteSocketOptionsBase,\n\tEventCallback,\n\tMiddleware,\n\tMiddlewareNext,\n\tRoomEventMiddleware,\n\tServerIncomingData,\n\tServerOutgoingData,\n\tSocketData,\n} from \"./types\";\n\ntype RequiredOptions =\n\t| \"middlewareTimeout\"\n\t| \"roomMiddlewareTimeout\"\n\t| \"authTimeout\"\n\t| \"broadcastRoom\"\n\t| \"onMiddlewareError\"\n\t| \"onMiddlewareTimeout\"\n\t| \"idleTimeout\"\n\t| \"sendPingsAutomatically\";\n\nexport abstract class ByteSocketServerBase<\n\tTEvents extends SocketEvents = SocketEvents,\n\tSD extends SocketData = SocketData,\n\tUpgradeCallback extends AnyCallback = AnyCallback,\n>\n\textends ByteSocketBase\n\timplements IByteSocket<TEvents, SD, UpgradeCallback>\n{\n\t// ──── Namespaces ────────────────────────────────────────────────────────────────────────\n\treadonly lifecycle: ILifecycleServer<TEvents, SD, UpgradeCallback>;\n\treadonly rooms: IRoomsServer<TEvents, SD>;\n\treadonly sockets = new Map<string, ISocket<TEvents, SD>>();\n\n\t// ──── States ────────────────────────────────────────────────────────────────────────\n\n\tprotected options: Omit<ByteSocketOptionsBase<TEvents, SD>, RequiredOptions | \"debug\" | \"serialization\" | \"msgpackrOptions\"> &\n\t\tPick<Required<ByteSocketOptionsBase<TEvents, SD>>, RequiredOptions>;\n\t#middlewares: Middleware<TEvents, SD>[] = [];\n\t#destroyed = false;\n\n\tconstructor(options: ByteSocketOptionsBase<TEvents, SD> = {}) {\n\t\tsuper(options);\n\n\t\tthis.options = {\n\t\t\t...options,\n\t\t\tmiddlewareTimeout: options.middlewareTimeout ?? 0,\n\t\t\troomMiddlewareTimeout: options.roomMiddlewareTimeout ?? 0,\n\t\t\tauthTimeout: options.authTimeout ?? 0,\n\t\t\tbroadcastRoom: options.broadcastRoom ?? \"__bytesocket_broadcast__\",\n\t\t\tonMiddlewareError: options.onMiddlewareError ?? \"ignore\",\n\t\t\tonMiddlewareTimeout: options.onMiddlewareTimeout ?? \"ignore\",\n\t\t\tidleTimeout: options.idleTimeout ?? 120000,\n\t\t\tsendPingsAutomatically: options.sendPingsAutomatically ?? true,\n\t\t};\n\n\t\tconst lifecycle: ILifecycleServer<TEvents, SD, UpgradeCallback> = {\n\t\t\tonUpgrade: (callback) => {\n\t\t\t\tthis._onLifecycle(LifecycleTypes.upgrade, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\toffUpgrade: (callback) => {\n\t\t\t\tthis._offLifecycle(LifecycleTypes.upgrade, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\tonceUpgrade: (callback) => {\n\t\t\t\tthis._onceLifecycle(LifecycleTypes.upgrade, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\n\t\t\tonOpen: (callback) => {\n\t\t\t\tthis._onLifecycle(LifecycleTypes.open, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\toffOpen: (callback) => {\n\t\t\t\tthis._offLifecycle(LifecycleTypes.open, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\tonceOpen: (callback) => {\n\t\t\t\tthis._onceLifecycle(LifecycleTypes.open, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\n\t\t\tonAuthSuccess: (callback) => {\n\t\t\t\tthis._onLifecycle(LifecycleTypes.auth_success, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\toffAuthSuccess: (callback) => {\n\t\t\t\tthis._offLifecycle(LifecycleTypes.auth_success, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\tonceAuthSuccess: (callback) => {\n\t\t\t\tthis._onceLifecycle(LifecycleTypes.auth_success, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\n\t\t\tonAuthError: (callback) => {\n\t\t\t\tthis._onLifecycle(LifecycleTypes.auth_error, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\toffAuthError: (callback) => {\n\t\t\t\tthis._offLifecycle(LifecycleTypes.auth_error, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\tonceAuthError: (callback) => {\n\t\t\t\tthis._onceLifecycle(LifecycleTypes.auth_error, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\n\t\t\tonMessage: (callback) => {\n\t\t\t\tthis._onLifecycle(LifecycleTypes.message, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\toffMessage: (callback) => {\n\t\t\t\tthis._offLifecycle(LifecycleTypes.message, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\tonceMessage: (callback) => {\n\t\t\t\tthis._onceLifecycle(LifecycleTypes.message, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\n\t\t\tonClose: (callback) => {\n\t\t\t\tthis._onLifecycle(LifecycleTypes.close, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\toffClose: (callback) => {\n\t\t\t\tthis._offLifecycle(LifecycleTypes.close, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\tonceClose: (callback) => {\n\t\t\t\tthis._onceLifecycle(LifecycleTypes.close, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\n\t\t\tonError: (callback) => {\n\t\t\t\tthis._onLifecycle(LifecycleTypes.error, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\toffError: (callback) => {\n\t\t\t\tthis._offLifecycle(LifecycleTypes.error, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\tonceError: (callback) => {\n\t\t\t\tthis._onceLifecycle(LifecycleTypes.error, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t};\n\n\t\tthis.lifecycle = lifecycle;\n\n\t\tconst roomsLifecycle: IRoomsLifecycleServer<TEvents, SD> = {\n\t\t\tonJoin: (callback) => {\n\t\t\t\tthis._onLifecycle(LifecycleTypes.join_room, callback);\n\t\t\t\treturn roomsLifecycle;\n\t\t\t},\n\t\t\toffJoin: (callback) => {\n\t\t\t\tthis._offLifecycle(LifecycleTypes.join_room, callback);\n\t\t\t\treturn roomsLifecycle;\n\t\t\t},\n\t\t\tonceJoin: (callback) => {\n\t\t\t\tthis._onceLifecycle(LifecycleTypes.join_room, callback);\n\t\t\t\treturn roomsLifecycle;\n\t\t\t},\n\n\t\t\tonLeave: (callback) => {\n\t\t\t\tthis._onLifecycle(LifecycleTypes.leave_room, callback);\n\t\t\t\treturn roomsLifecycle;\n\t\t\t},\n\t\t\toffLeave: (callback) => {\n\t\t\t\tthis._offLifecycle(LifecycleTypes.leave_room, callback);\n\t\t\t\treturn roomsLifecycle;\n\t\t\t},\n\t\t\tonceLeave: (callback) => {\n\t\t\t\tthis._onceLifecycle(LifecycleTypes.leave_room, callback);\n\t\t\t\treturn roomsLifecycle;\n\t\t\t},\n\t\t};\n\n\t\tconst roomsBulkLifecycle: IRoomsBulkLifecycleServer<TEvents, SD> = {\n\t\t\tonJoin: (callback) => {\n\t\t\t\tthis._onLifecycle(LifecycleTypes.join_rooms, callback);\n\t\t\t\treturn roomsBulkLifecycle;\n\t\t\t},\n\t\t\toffJoin: (callback) => {\n\t\t\t\tthis._offLifecycle(LifecycleTypes.join_rooms, callback);\n\t\t\t\treturn roomsBulkLifecycle;\n\t\t\t},\n\t\t\tonceJoin: (callback) => {\n\t\t\t\tthis._onceLifecycle(LifecycleTypes.join_rooms, callback);\n\t\t\t\treturn roomsBulkLifecycle;\n\t\t\t},\n\n\t\t\tonLeave: (callback) => {\n\t\t\t\tthis._onLifecycle(LifecycleTypes.leave_rooms, callback);\n\t\t\t\treturn roomsBulkLifecycle;\n\t\t\t},\n\t\t\toffLeave: (callback) => {\n\t\t\t\tthis._offLifecycle(LifecycleTypes.leave_rooms, callback);\n\t\t\t\treturn roomsBulkLifecycle;\n\t\t\t},\n\t\t\tonceLeave: (callback) => {\n\t\t\t\tthis._onceLifecycle(LifecycleTypes.leave_rooms, callback);\n\t\t\t\treturn roomsBulkLifecycle;\n\t\t\t},\n\t\t};\n\n\t\tthis.rooms = {\n\t\t\tpublishRaw: this.publishRaw.bind(this),\n\t\t\temit: this.#publish.bind(this),\n\t\t\ton: this.#onRoom.bind(this),\n\t\t\toff: this.#offRoom.bind(this),\n\t\t\tonce: this.#onceRoom.bind(this),\n\t\t\tlifecycle: roomsLifecycle,\n\t\t\tbulk: {\n\t\t\t\temit: this.#publishMany.bind(this),\n\t\t\t\tlifecycle: roomsBulkLifecycle,\n\t\t\t},\n\t\t};\n\t}\n\n\tabstract attach(server: unknown, path: string): this;\n\tabstract destroy(): void;\n\n\tprotected abstract publishRaw(room: string, message: ServerOutgoingData, isBinary?: boolean, compress?: boolean): typeof this.rooms;\n\n\tprotected _destroy(): void {\n\t\tthis.#destroyed = true;\n\n\t\tfor (const socket of this.sockets.values()) {\n\t\t\tif (!socket.isClosed) {\n\t\t\t\tsocket.close(1001, \"server destroy\");\n\t\t\t}\n\t\t}\n\t\tthis.sockets.clear();\n\n\t\tthis._clearCallbacks();\n\t\tthis.#middlewares = [];\n\t}\n\n\temit<E extends StringNumberKeys<TEvents[\"emit\"]>, D extends NonNullable<TEvents[\"emit\"]>[E]>(event: E, data: D): this {\n\t\tif (this.#destroyed) {\n\t\t\treturn this;\n\t\t}\n\t\tconst message = this.encode({ event, data });\n\t\tthis.publishRaw(this.options.broadcastRoom, message);\n\t\treturn this;\n\t}\n\n\t#publish<\n\t\tR extends StringKeys<TEvents[\"emitRoom\"]>,\n\t\tE extends StringNumberKeys<NonNullable<TEvents[\"emitRoom\"]>[R]>,\n\t\tD extends NonNullable<TEvents[\"emitRoom\"]>[R][E],\n\t>(room: R, event: E, data: D): typeof this.rooms {\n\t\tif (this.#destroyed) {\n\t\t\treturn this.rooms;\n\t\t}\n\t\tconst message = this.encode({ room, event, data });\n\t\tthis.publishRaw(room, message);\n\t\treturn this.rooms;\n\t}\n\n\t#publishMany<\n\t\tRs extends NonNullable<TEvents[\"emitRooms\"]>[\"rooms\"],\n\t\tE extends StringNumberKeys<EventsForRooms<NonNullable<TEvents[\"emitRooms\"]>, Rs>>,\n\t\tD extends NonNullable<EventsForRooms<NonNullable<TEvents[\"emitRooms\"]>, Rs>>[E],\n\t>(rooms: Rs, event: E, data: D): typeof this.rooms.bulk {\n\t\tif (this.#destroyed) {\n\t\t\treturn this.rooms.bulk;\n\t\t}\n\t\tconst message = this.encode({ rooms, event, data });\n\t\tfor (const room of rooms) {\n\t\t\tthis.publishRaw(room, message);\n\t\t}\n\t\treturn this.rooms.bulk;\n\t}\n\n\ton<E extends StringNumberKeys<TEvents[\"listen\"]>, D extends NonNullable<TEvents[\"listen\"]>[E]>(\n\t\tevent: E,\n\t\tcallback: EventCallback<TEvents, SD, D>,\n\t): this {\n\t\tthis._on(event, callback);\n\t\treturn this;\n\t}\n\n\toff<E extends StringNumberKeys<TEvents[\"listen\"]>, D extends NonNullable<TEvents[\"listen\"]>[E]>(\n\t\tevent: E,\n\t\tcallback?: EventCallback<TEvents, SD, D>,\n\t): this {\n\t\tthis._off(event, callback);\n\t\treturn this;\n\t}\n\n\tonce<E extends StringNumberKeys<TEvents[\"listen\"]>, D extends NonNullable<TEvents[\"listen\"]>[E]>(\n\t\tevent: E,\n\t\tcallback: EventCallback<TEvents, SD, D>,\n\t): this {\n\t\tthis._once(event, callback);\n\t\treturn this;\n\t}\n\n\t#onRoom<\n\t\tR extends StringKeys<TEvents[\"listenRoom\"]>,\n\t\tE extends StringNumberKeys<NonNullable<TEvents[\"listenRoom\"]>[R]>,\n\t\tD extends NonNullable<TEvents[\"listenRoom\"]>[R][E],\n\t>(room: R, event: E, callback: RoomEventMiddleware<TEvents, SD, D>): typeof this.rooms {\n\t\tthis._onRoom(room, event, callback);\n\t\treturn this.rooms;\n\t}\n\n\t#offRoom<\n\t\tR extends StringKeys<TEvents[\"listenRoom\"]>,\n\t\tE extends StringNumberKeys<NonNullable<TEvents[\"listenRoom\"]>[R]>,\n\t\tD extends NonNullable<TEvents[\"listenRoom\"]>[R][E],\n\t>(room: R, event?: E, callback?: RoomEventMiddleware<TEvents, SD, D>): typeof this.rooms {\n\t\tthis._offRoom(room, event, callback);\n\t\treturn this.rooms;\n\t}\n\n\t#onceRoom<\n\t\tR extends StringKeys<TEvents[\"listenRoom\"]>,\n\t\tE extends StringNumberKeys<NonNullable<TEvents[\"listenRoom\"]>[R]>,\n\t\tD extends NonNullable<TEvents[\"listenRoom\"]>[R][E],\n\t>(room: R, event: E, callback: RoomEventMiddleware<TEvents, SD, D>): typeof this.rooms {\n\t\tthis._onceRoom(room, event, callback);\n\t\treturn this.rooms;\n\t}\n\n\tuse(fn: Middleware<TEvents, SD>): this {\n\t\tthis.#middlewares.push(fn);\n\t\treturn this;\n\t}\n\n\t#isPromiseLike(value: unknown): value is PromiseLike<unknown> {\n\t\treturn !!value && typeof (value as PromiseLike<unknown>).then === \"function\";\n\t}\n\n\t#runMiddlewares<R extends string, E extends string | number, D>(\n\t\tsocket: ISocket<TEvents, SD>,\n\t\tctx: UserMessage<R, E, D>,\n\t\tfinalCallback: () => void,\n\t): void {\n\t\tlet index = 0;\n\t\tlet aborted = false;\n\n\t\tconst stack = Array.from(this.#middlewares);\n\n\t\tconst next: MiddlewareNext = (error) => {\n\t\t\tif (aborted) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (error) {\n\t\t\t\taborted = true;\n\t\t\t\tconst isTimeout = error instanceof Error && error.name === \"TimeoutError\";\n\t\t\t\tconst phase = isTimeout ? \"middlewareTimeout\" : \"middleware\";\n\t\t\t\tthis._triggerCallbacks(this._lifecycleCallbacksMap.get(LifecycleTypes.error), socket, { phase, error });\n\n\t\t\t\tconst option = isTimeout ? this.options.onMiddlewareTimeout : this.options.onMiddlewareError;\n\t\t\t\tif (option === \"close\") {\n\t\t\t\t\tsocket.close(1011, error instanceof Error ? error.message : String(error));\n\t\t\t\t} else if (typeof option === \"function\") {\n\t\t\t\t\toption(error, socket);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (index >= stack.length) {\n\t\t\t\ttry {\n\t\t\t\t\treturn finalCallback();\n\t\t\t\t} catch (err) {\n\t\t\t\t\tthis._triggerCallbacks(this._lifecycleCallbacksMap.get(LifecycleTypes.error), socket, { phase: \"finalCallback\", error: err });\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst middleware = stack[index++];\n\t\t\tlet called = false;\n\t\t\tlet timeoutId: ReturnType<typeof setTimeout> | null = null;\n\n\t\t\tconst execution = new Promise<void>((resolve, reject) => {\n\t\t\t\ttry {\n\t\t\t\t\tconst result = middleware(socket, ctx, (err) => {\n\t\t\t\t\t\tif (called) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcalled = true;\n\t\t\t\t\t\tif (err) {\n\t\t\t\t\t\t\treject(err);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tresolve();\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\n\t\t\t\t\tif (this.#isPromiseLike(result)) {\n\t\t\t\t\t\tresult.then(\n\t\t\t\t\t\t\t() => {\n\t\t\t\t\t\t\t\tif (!called) {\n\t\t\t\t\t\t\t\t\tcalled = true;\n\t\t\t\t\t\t\t\t\tresolve();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t(err) => {\n\t\t\t\t\t\t\t\tif (!called) {\n\t\t\t\t\t\t\t\t\tcalled = true;\n\t\t\t\t\t\t\t\t\treject(err);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t} catch (syncErr) {\n\t\t\t\t\tif (!called) {\n\t\t\t\t\t\tcalled = true;\n\t\t\t\t\t\treject(syncErr);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tconst tasks: Promise<void>[] = [execution];\n\n\t\t\tif (this.options.middlewareTimeout > 0) {\n\t\t\t\tconst timeout = new Promise<void>((_, reject) => {\n\t\t\t\t\ttimeoutId = setTimeout(() => {\n\t\t\t\t\t\tif (!called) {\n\t\t\t\t\t\t\tcalled = true;\n\t\t\t\t\t\t\tconst timeoutError = new Error(`Middleware timeout after ${this.options.middlewareTimeout}ms`);\n\t\t\t\t\t\t\ttimeoutError.name = \"TimeoutError\";\n\t\t\t\t\t\t\treject(timeoutError);\n\t\t\t\t\t\t}\n\t\t\t\t\t}, this.options.middlewareTimeout);\n\t\t\t\t});\n\t\t\t\ttasks.push(timeout);\n\t\t\t}\n\n\t\t\tPromise.race(tasks)\n\t\t\t\t.then(() => next())\n\t\t\t\t.catch((err) => next(err))\n\t\t\t\t.finally(() => {\n\t\t\t\t\tif (timeoutId) {\n\t\t\t\t\t\tclearTimeout(timeoutId);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t};\n\n\t\tnext();\n\t}\n\n\tget destroyed(): boolean {\n\t\treturn this.#destroyed;\n\t}\n\n\t#rawMessageDescription(message: ServerIncomingData, isBinary: boolean): string {\n\t\tif (Array.isArray(message)) {\n\t\t\tconst total = message.reduce((s, b) => s + b.length, 0);\n\t\t\treturn `fragmented (${message.length} parts, ${total} bytes)`;\n\t\t}\n\t\tif (isBinary) {\n\t\t\tconst len = Buffer.isBuffer(message) ? message.length : message.byteLength;\n\t\t\treturn `binary (${len} bytes)`;\n\t\t}\n\t\treturn typeof message === \"string\" ? message : new TextDecoder().decode(message);\n\t}\n\n\tprotected message(socket: ISocket<TEvents, SD>, message: ServerIncomingData, isBinary: boolean) {\n\t\tthis._runSyncHooks(this._lifecycleCallbacksMap.get(LifecycleTypes.message), [socket, message, isBinary], (error) => {\n\t\t\tif (error != null) {\n\t\t\t\tthis._triggerCallbacks(this._lifecycleCallbacksMap.get(LifecycleTypes.error), socket, { phase: \"onMessage\", error });\n\t\t\t}\n\t\t});\n\n\t\tif (isBinary && (message.byteLength === 0 || (message instanceof Buffer && message.length === 0))) {\n\t\t\tsocket.sendRaw(new Uint8Array(0), true);\n\t\t\treturn;\n\t\t}\n\n\t\tlet parsed;\n\t\ttry {\n\t\t\tparsed = this.decode(message, isBinary);\n\t\t} catch (error) {\n\t\t\tconst raw = this.#rawMessageDescription(message, isBinary);\n\t\t\tthis._triggerCallbacks(this._lifecycleCallbacksMap.get(LifecycleTypes.error), socket, { phase: \"decode\", raw, error });\n\t\t\tsocket.close(1008, \"decode error\");\n\t\t\treturn;\n\t\t}\n\n\t\tif (parsed == null || typeof parsed !== \"object\") {\n\t\t\tconst error = new Error(\"Message must be an object\");\n\t\t\tthis._triggerCallbacks(this._lifecycleCallbacksMap.get(LifecycleTypes.error), socket, {\n\t\t\t\tphase: \"validation\",\n\t\t\t\traw: JSON.stringify(parsed),\n\t\t\t\terror,\n\t\t\t});\n\t\t\tsocket.close(1008, \"bad format\");\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.#handleAuthMessage(socket, parsed)) {\n\t\t\treturn;\n\t\t}\n\t\tif (!socket.isAuthenticated) {\n\t\t\treturn;\n\t\t}\n\t\tif (this.#handleJoinRoomMessage(socket, parsed)) {\n\t\t\treturn;\n\t\t}\n\t\tif (this.#handleLeaveRoomMessage(socket, parsed)) {\n\t\t\treturn;\n\t\t}\n\t\tif (this.#handleJoinRoomsMessage(socket, parsed)) {\n\t\t\treturn;\n\t\t}\n\t\tif (this.#handleLeaveRoomsMessage(socket, parsed)) {\n\t\t\treturn;\n\t\t}\n\t\tthis.#runMiddlewares(socket, parsed as UserMessage, () => {\n\t\t\tif (this.#handleRoomsEventMessage(socket, parsed)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (this.#handleRoomEventMessage(socket, parsed)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (this.#handleEventMessage(socket, parsed)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t});\n\t}\n\n\tprotected close(socket: ISocket<TEvents, SD>, code: number, reason: Buffer | ArrayBuffer) {\n\t\tif (this._debug && code === 4008) {\n\t\t\tconsole.warn(`Auth timeout for socket ${socket.id}`);\n\t\t}\n\t\tthis.sockets.delete(socket.id);\n\t\tsocket.close(code, Buffer.from(reason as ArrayBuffer).toString(\"utf8\"));\n\t\tthis._runSyncHooks(this._lifecycleCallbacksMap.get(LifecycleTypes.close), [socket, code, reason], (error) => {\n\t\t\tif (error != null) {\n\t\t\t\tthis._triggerCallbacks(this._lifecycleCallbacksMap.get(LifecycleTypes.error), socket, { phase: \"onClose\", error });\n\t\t\t}\n\t\t});\n\t}\n\n\t#handleAuthMessage<T extends object>(socket: ISocket<TEvents, SD>, parsed: T): boolean {\n\t\tif (!this._isLifecyclePayloadMessage(LifecycleTypes.auth, parsed)) {\n\t\t\treturn false;\n\t\t}\n\t\tsocket._handleAuth(parsed, this.options.auth, this.options.authTimeout, (err) => {\n\t\t\tif (err == null) {\n\t\t\t\tthis._runSyncHooks(this._lifecycleCallbacksMap.get(LifecycleTypes.auth_success), [socket], (error) => {\n\t\t\t\t\tif (error != null) {\n\t\t\t\t\t\tthis._triggerCallbacks(this._lifecycleCallbacksMap.get(LifecycleTypes.error), socket, { phase: \"onAuthSuccess\", error });\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tthis._runSyncHooks(this._lifecycleCallbacksMap.get(LifecycleTypes.open), [socket], (error) => {\n\t\t\t\t\tif (error != null) {\n\t\t\t\t\t\tthis._triggerCallbacks(this._lifecycleCallbacksMap.get(LifecycleTypes.error), socket, { phase: \"onOpen\", error });\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tconst ctx: ErrorContext = {\n\t\t\t\t\tphase: \"auth\",\n\t\t\t\t\terror: err instanceof Error ? err : new Error(String(err)),\n\t\t\t\t\tcode: 4003,\n\t\t\t\t};\n\t\t\t\tthis._runSyncHooks(this._lifecycleCallbacksMap.get(LifecycleTypes.auth_error), [socket, ctx], (error) => {\n\t\t\t\t\tif (error != null) {\n\t\t\t\t\t\tthis._triggerCallbacks(this._lifecycleCallbacksMap.get(LifecycleTypes.error), socket, { phase: \"onAuthError\", error });\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\t\treturn true;\n\t}\n\n\t#handleJoinRoomMessage<T extends object>(socket: ISocket<TEvents, SD>, parsed: T): boolean {\n\t\tif (!this._isLifecycleRoomMessage(LifecycleTypes.join_room, parsed)) {\n\t\t\treturn false;\n\t\t}\n\t\tthis.#runAsyncHooksOrNext(this._lifecycleCallbacksMap.get(LifecycleTypes.join_room), [socket, parsed.room], (error) => {\n\t\t\tif (error == null) {\n\t\t\t\tsocket.rooms.join(parsed.room);\n\t\t\t\tsocket.send({ type: LifecycleTypes.join_room_success, room: parsed.room });\n\t\t\t} else {\n\t\t\t\tsocket.send({ type: LifecycleTypes.join_room_error, room: parsed.room, data: { phase: \"onJoinRoom\", error } });\n\t\t\t}\n\t\t});\n\t\treturn true;\n\t}\n\n\t#handleLeaveRoomMessage<T extends object>(socket: ISocket<TEvents, SD>, parsed: T): boolean {\n\t\tif (!this._isLifecycleRoomMessage(LifecycleTypes.leave_room, parsed)) {\n\t\t\treturn false;\n\t\t}\n\t\tthis.#runAsyncHooksOrNext(this._lifecycleCallbacksMap.get(LifecycleTypes.leave_room), [socket, parsed.room], (error) => {\n\t\t\tif (error == null) {\n\t\t\t\tsocket.rooms.leave(parsed.room);\n\t\t\t\tsocket.send({ type: LifecycleTypes.leave_room_success, room: parsed.room });\n\t\t\t} else {\n\t\t\t\tsocket.send({ type: LifecycleTypes.leave_room_error, room: parsed.room, data: { phase: \"onLeaveRoom\", error } });\n\t\t\t}\n\t\t});\n\t\treturn true;\n\t}\n\n\t#handleJoinRoomsMessage<T extends object>(socket: ISocket<TEvents, SD>, parsed: T): boolean {\n\t\tif (!this._isLifecycleRoomsMessage(LifecycleTypes.join_rooms, parsed)) {\n\t\t\treturn false;\n\t\t}\n\t\tthis.#runAsyncHooksOrNext(this._lifecycleCallbacksMap.get(LifecycleTypes.join_rooms), [socket, parsed.rooms], (error) => {\n\t\t\tif (error == null) {\n\t\t\t\tsocket.rooms.bulk.join(parsed.rooms);\n\t\t\t\tsocket.send({ type: LifecycleTypes.join_rooms_success, rooms: parsed.rooms });\n\t\t\t} else {\n\t\t\t\tsocket.send({ type: LifecycleTypes.join_rooms_error, rooms: parsed.rooms, data: { phase: \"onJoinRooms\", error } });\n\t\t\t}\n\t\t});\n\t\treturn true;\n\t}\n\n\t#handleLeaveRoomsMessage<T extends object>(socket: ISocket<TEvents, SD>, parsed: T): boolean {\n\t\tif (!this._isLifecycleRoomsMessage(LifecycleTypes.leave_rooms, parsed)) {\n\t\t\treturn false;\n\t\t}\n\t\tthis.#runAsyncHooksOrNext(this._lifecycleCallbacksMap.get(LifecycleTypes.leave_rooms), [socket, parsed.rooms], (error) => {\n\t\t\tif (error == null) {\n\t\t\t\tsocket.rooms.bulk.leave(parsed.rooms);\n\t\t\t\tsocket.send({ type: LifecycleTypes.leave_rooms_success, rooms: parsed.rooms });\n\t\t\t} else {\n\t\t\t\tsocket.send({ type: LifecycleTypes.leave_rooms_error, rooms: parsed.rooms, data: { phase: \"onLeaveRooms\", error } });\n\t\t\t}\n\t\t});\n\t\treturn true;\n\t}\n\n\t#handleRoomsEventMessage<T extends object>(socket: ISocket<TEvents, SD>, parsed: T): boolean {\n\t\tif (!this._isRoomsEventMessage(parsed)) {\n\t\t\treturn false;\n\t\t}\n\t\tconst message = this.encode({ rooms: parsed.rooms, event: parsed.event, data: parsed.data });\n\t\tfor (const room of parsed.rooms) {\n\t\t\tthis.#runAsyncHooksOrNext(this._roomCallbacksMap.get(room)?.get(parsed.event), [socket, parsed.data], (error) => {\n\t\t\t\tif (error == null) {\n\t\t\t\t\tsocket.rooms.publishRaw(room, message);\n\t\t\t\t} else {\n\t\t\t\t\tthis._triggerCallbacks(this._lifecycleCallbacksMap.get(LifecycleTypes.error), socket, {\n\t\t\t\t\t\tphase: \"rooms message\",\n\t\t\t\t\t\traw: JSON.stringify(parsed),\n\t\t\t\t\t\terror,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\treturn true;\n\t}\n\n\t#handleRoomEventMessage<T extends object>(socket: ISocket<TEvents, SD>, parsed: T): boolean {\n\t\tif (!this._isRoomEventMessage(parsed)) {\n\t\t\treturn false;\n\t\t}\n\t\tthis.#runAsyncHooksOrNext(this._roomCallbacksMap.get(parsed.room)?.get(parsed.event), [socket, parsed.data], (error) => {\n\t\t\tif (error == null) {\n\t\t\t\tconst message = this.encode({ room: parsed.room, event: parsed.event, data: parsed.data });\n\t\t\t\tsocket.rooms.publishRaw(parsed.room, message);\n\t\t\t} else {\n\t\t\t\tthis._triggerCallbacks(this._lifecycleCallbacksMap.get(LifecycleTypes.error), socket, {\n\t\t\t\t\tphase: \"room message\",\n\t\t\t\t\traw: JSON.stringify(parsed),\n\t\t\t\t\terror,\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\t\treturn true;\n\t}\n\n\t#handleEventMessage<T extends object>(socket: ISocket<TEvents, SD>, parsed: T): boolean {\n\t\tif (!this._isEventMessage(parsed)) {\n\t\t\treturn false;\n\t\t}\n\t\tthis._triggerCallbacks(this._callbacksMap.get(parsed.event), socket, parsed.data);\n\t\treturn true;\n\t}\n\n\tprotected _runSyncHooks<Args extends Array<unknown>>(callbackSet: Set<AnyCallback> | undefined, args: Args, next: MiddlewareNext): void {\n\t\tif (!callbackSet) {\n\t\t\treturn next();\n\t\t}\n\t\tlet firstError: unknown = null;\n\t\tfor (const callback of callbackSet) {\n\t\t\ttry {\n\t\t\t\tcallback(...args);\n\t\t\t} catch (err) {\n\t\t\t\tif (this._debug) {\n\t\t\t\t\tconsole.error(err);\n\t\t\t\t}\n\t\t\t\tfirstError = firstError ?? err;\n\t\t\t}\n\t\t}\n\t\tnext(firstError);\n\t}\n\n\t#runAsyncHooksOrNext<Args extends Array<unknown>>(callbacks: Set<AnyCallback> | undefined, args: Args, finalCallback: MiddlewareNext): void {\n\t\tif (!callbacks || callbacks.size === 0) {\n\t\t\ttry {\n\t\t\t\tfinalCallback();\n\t\t\t} catch (err) {\n\t\t\t\tconst socket = args[0] instanceof SocketServerBase ? args[0] : undefined;\n\t\t\t\tthis._triggerCallbacks(this._lifecycleCallbacksMap.get(LifecycleTypes.error), socket, { phase: \"asyncHookFinal\", error: err });\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tconst stack = Array.from(callbacks);\n\t\tlet index = 0;\n\n\t\tconst next: MiddlewareNext = (error) => {\n\t\t\tif (error) {\n\t\t\t\treturn finalCallback(error);\n\t\t\t}\n\t\t\tif (index >= stack.length) {\n\t\t\t\ttry {\n\t\t\t\t\treturn finalCallback();\n\t\t\t\t} catch (err) {\n\t\t\t\t\tconst socket = args[0] instanceof SocketServerBase ? args[0] : undefined;\n\t\t\t\t\tthis._triggerCallbacks(this._lifecycleCallbacksMap.get(LifecycleTypes.error), socket, { phase: \"asyncHookFinal\", error: err });\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst callback = stack[index++];\n\t\t\tlet called = false;\n\t\t\tlet timeoutId: ReturnType<typeof setTimeout> | null = null;\n\n\t\t\tconst execution = new Promise<void>((resolve, reject) => {\n\t\t\t\ttry {\n\t\t\t\t\tconst result = callback(...args, (err?: unknown) => {\n\t\t\t\t\t\tif (called) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcalled = true;\n\t\t\t\t\t\tif (err) {\n\t\t\t\t\t\t\treject(err);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tresolve();\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\n\t\t\t\t\tif (this.#isPromiseLike(result)) {\n\t\t\t\t\t\tresult.then(\n\t\t\t\t\t\t\t() => {\n\t\t\t\t\t\t\t\tif (!called) {\n\t\t\t\t\t\t\t\t\tcalled = true;\n\t\t\t\t\t\t\t\t\tresolve();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t(err) => {\n\t\t\t\t\t\t\t\tif (!called) {\n\t\t\t\t\t\t\t\t\tcalled = true;\n\t\t\t\t\t\t\t\t\treject(err);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t} catch (syncErr) {\n\t\t\t\t\tif (!called) {\n\t\t\t\t\t\tcalled = true;\n\t\t\t\t\t\treject(syncErr);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tconst tasks: Promise<void>[] = [execution];\n\n\t\t\tif (this.options.roomMiddlewareTimeout > 0) {\n\t\t\t\tconst timeout = new Promise<void>((_, reject) => {\n\t\t\t\t\ttimeoutId = setTimeout(() => {\n\t\t\t\t\t\tif (!called) {\n\t\t\t\t\t\t\tcalled = true;\n\t\t\t\t\t\t\tconst timeoutError = new Error(`Room middleware timeout after ${this.options.roomMiddlewareTimeout}ms`);\n\t\t\t\t\t\t\ttimeoutError.name = \"TimeoutError\";\n\t\t\t\t\t\t\treject(timeoutError);\n\t\t\t\t\t\t}\n\t\t\t\t\t}, this.options.roomMiddlewareTimeout);\n\t\t\t\t});\n\t\t\t\ttasks.push(timeout);\n\t\t\t}\n\n\t\t\tPromise.race(tasks)\n\t\t\t\t.then(() => next())\n\t\t\t\t.catch((err) => next(err))\n\t\t\t\t.finally(() => {\n\t\t\t\t\tif (timeoutId) {\n\t\t\t\t\t\tclearTimeout(timeoutId);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t};\n\n\t\tnext();\n\t}\n}\n"],"mappings":";;;;;AAeA,IAAsB,mBAAtB,MAGE;CACD,AAAS;CAET,UAAe,EAAE;CACjB,SAAc,EAAE;CAEhB;CAGA,aAAwBA,2BAAU;CAClC,aAAmD;CACnD,UAAmB;CAEnB,IAAI,kBAA2B;EAC9B,OAAO,KAAKC,eAAeD,2BAAU,QAAQ,KAAKC,eAAeD,2BAAU;;CAE5E,IAAI,WAAoB;EACvB,OAAO,KAAKE;;CAEb,IAAI,UAAmB;EACtB,OAAO,CAAC,KAAKA,WAAW,KAAK;;CAI9B,IAAI,KAAa;EAChB,OAAO,KAAK,SAAS;;CAEtB,IAAI,MAAc;EACjB,OAAO,KAAK,SAAS;;CAEtB,IAAI,QAAgB;EACnB,OAAO,KAAK,SAAS;;CAEtB,IAAI,SAAiB;EACpB,OAAO,KAAK,SAAS;;CAEtB,IAAI,gBAAwB;EAC3B,OAAO,KAAK,SAAS;;CAEtB,IAAI,YAAoB;EACvB,OAAO,KAAK,SAAS;;CAEtB,IAAI,OAAe;EAClB,OAAO,KAAK,SAAS;;CAEtB,IAAI,gBAAwB;EAC3B,OAAO,KAAK,SAAS;;CAKtB,YACC,QAGC;EACD,KAAKC,UAAU;EACf,KAAK,QAAQ;GACZ,YAAY,KAAK,WAAW,KAAK,KAAK;GACtC,MAAM,KAAKC,SAAS,KAAK,KAAK;GAC9B,MAAM,KAAK,SAAS,KAAK,KAAK;GAC9B,OAAO,KAAK,UAAU,KAAK,KAAK;GAChC,MAAM,KAAK,YAAY,KAAK,KAAK;GACjC,MAAM;IACL,MAAM,KAAKC,aAAa,KAAK,KAAK;IAClC,MAAM,KAAKC,WAAW,KAAK,KAAK;IAChC,OAAO,KAAKC,YAAY,KAAK,KAAK;IAClC;GACD;;CAeF,AAAU,iBAAuB;CAEjC,AAAU,iBAAuB;CAEjC,KAA6F,OAAU,MAAe;EACrH,KAAK,KAAK;GAAE;GAAO;GAAM,CAAC;EAC1B,OAAO;;CAGR,KAAqD,SAA8D;EAClH,IAAI,CAAC,KAAK,SACT,OAAO;EAER,MAAM,UAAU,KAAKJ,QAAQ,QAAQ;EACrC,KAAK,QAAQ,QAAQ;EACrB,OAAO;;CAGR,UAAkG,OAAU,MAAe;EAC1H,IAAI,CAAC,KAAK,SACT,OAAO;EAER,MAAM,UAAU,KAAKA,QAAQ;GAAE;GAAO;GAAM,CAAC;EAC7C,KAAK,WAAW,KAAK,eAAe,QAAQ;EAC5C,OAAO;;CAGR,eAA+D,SAA8D;EAC5H,IAAI,KAAKD,SACR;EAED,MAAM,UAAU,KAAKC,QAAQ,QAAQ;EACrC,KAAK,QAAQ,QAAQ;;CAGtB,SAIE,MAAS,OAAU,MAA4B;EAChD,IAAI,CAAC,KAAK,SACT,OAAO,KAAK;EAEb,MAAM,UAAU,KAAKA,QAAQ;GAAE;GAAM;GAAO;GAAM,CAAC;EACnD,KAAK,WAAW,MAAM,QAAQ;EAC9B,OAAO,KAAK;;CAGb,aAIE,OAAW,OAAU,MAAiC;EACvD,IAAI,CAAC,KAAK,SACT,OAAO,KAAK,MAAM;EAEnB,MAAM,UAAU,KAAKA,QAAQ;GAAE;GAAO;GAAO;GAAM,CAAC;EACpD,KAAK,MAAM,QAAQ,OAClB,KAAK,WAAW,MAAM,QAAQ;EAE/B,OAAO,KAAK,MAAM;;CAGnB,WAAW,OAAyC;EACnD,IAAI,CAAC,KAAK,SACT,OAAO,KAAK,MAAM;EAEnB,KAAK,MAAM,QAAQ,OAClB,KAAK,SAAS,KAAK;EAEpB,OAAO,KAAK,MAAM;;CAGnB,YAAY,OAAyC;EACpD,IAAI,CAAC,KAAK,SACT,OAAO,KAAK,MAAM;EAEnB,KAAK,MAAM,QAAQ,OAClB,KAAK,UAAU,KAAK;EAErB,OAAO,KAAK,MAAM;;CAGnB,AAAU,SAAe;EACxB,KAAKD,UAAU;EACf,KAAKM,iBAAiB;EACtB,KAAK,gBAAgB;;CAGtB,YACC,QACA,MACA,aACA,MACC;EACD,IAAI,QAAQ,WAAW,MAAM;GAC5B,IAAI,KAAKP,eAAeD,2BAAU,MACjC;GAED,KAAKC,aAAaD,2BAAU;GAC5B,IAAI,cAAc,GACjB,KAAKS,aAAa,iBAAiB;IAClC,IAAI,CAAC,KAAK,YAAY,CAAC,KAAK,iBAAiB;KAC5C,MAAM,sBAAM,IAAI,MAAM,eAAe;KACrC,KAAKC,eAAe;MAAE,OAAO;MAAQ,OAAO;MAAK,MAAM;MAAM,CAAC;KAC9D,KAAK,IAAI;;MAER,YAAY;GAEhB,IAAI;IACH,KAAK,MAAM,OAAO,OAAO,SAAS,UAAU;KAC3C,IAAI,OAAO;MACV,MAAM,MAAM,yBAAS,IAAI,MAAM,cAAc;MAC7C,KAAKA,eAAe;OAAE,OAAO;OAAQ,OAAO;OAAK,MAAM;OAAM,CAAC;MAC9D,KAAK,IAAI;MACT;;KAED,KAAKC,gBAAgB,QAAQ;KAC7B,KAAK,MAAM,KAAK,KAAK,cAAc;KACnC,KAAK,gBAAgB;KACrB,MAAM;MACL;YACM,KAAK;IACb,KAAKD,eAAe;KAAE,OAAO;KAAQ,OAAO;KAAK,MAAM;KAAM,CAAC;IAC9D,KAAK,IAAI;;SAEJ;GACN,KAAKE,eAAe;GACpB,KAAK,gBAAgB;GACrB,MAAM;;;CAIR,gBAAgB;EACf,IAAI,KAAKV,WAAW,KAAKD,eAAeD,2BAAU,MACjD;EAED,KAAKC,aAAaD,2BAAU;EAC5B,KAAK,MAAM,KAAK,KAAK,cAAc;;CAGpC,gBAAmB,SAAkB;EACpC,IAAI,KAAKE,WAAW,KAAKD,eAAeD,2BAAU,SACjD;EAED,KAAKQ,iBAAiB;EACtB,KAAKP,aAAaD,2BAAU;EAC5B,KAAK,UAAU;EACf,KAAKa,eAAe,EAAE,MAAMC,gCAAe,cAAc,CAAC;;CAG3D,eAAe,KAAyB;EACvC,IAAI,KAAKZ,WAAW,KAAKD,eAAeD,2BAAU,SACjD;EAED,KAAKQ,iBAAiB;EACtB,KAAKP,aAAaD,2BAAU;EAC5B,KAAKa,eAAe;GAAE,MAAMC,gCAAe;GAAY,MAAM;GAAK,CAAC;EACnE,KAAK,MAAM,IAAI,MAAM,IAAI,MAAM;;CAGhC,kBAAwB;EACvB,IAAI,KAAKL,YAAY;GACpB,aAAa,KAAKA,WAAW;GAC7B,KAAKA,aAAa;;;;;;;ACtOrB,IAAsB,uBAAtB,cAKSM,gCAET;CAEC,AAAS;CACT,AAAS;CACT,AAAS,0BAAU,IAAI,KAAmC;CAI1D,AAAU;CAEV,eAA0C,EAAE;CAC5C,aAAa;CAEb,YAAY,UAA8C,EAAE,EAAE;EAC7D,MAAM,QAAQ;EAEd,KAAK,UAAU;GACd,GAAG;GACH,mBAAmB,QAAQ,qBAAqB;GAChD,uBAAuB,QAAQ,yBAAyB;GACxD,aAAa,QAAQ,eAAe;GACpC,eAAe,QAAQ,iBAAiB;GACxC,mBAAmB,QAAQ,qBAAqB;GAChD,qBAAqB,QAAQ,uBAAuB;GACpD,aAAa,QAAQ,eAAe;GACpC,wBAAwB,QAAQ,0BAA0B;GAC1D;EAED,MAAM,YAA4D;GACjE,YAAY,aAAa;IACxB,KAAK,aAAaC,gCAAe,SAAS,SAAS;IACnD,OAAO;;GAER,aAAa,aAAa;IACzB,KAAK,cAAcA,gCAAe,SAAS,SAAS;IACpD,OAAO;;GAER,cAAc,aAAa;IAC1B,KAAK,eAAeA,gCAAe,SAAS,SAAS;IACrD,OAAO;;GAGR,SAAS,aAAa;IACrB,KAAK,aAAaA,gCAAe,MAAM,SAAS;IAChD,OAAO;;GAER,UAAU,aAAa;IACtB,KAAK,cAAcA,gCAAe,MAAM,SAAS;IACjD,OAAO;;GAER,WAAW,aAAa;IACvB,KAAK,eAAeA,gCAAe,MAAM,SAAS;IAClD,OAAO;;GAGR,gBAAgB,aAAa;IAC5B,KAAK,aAAaA,gCAAe,cAAc,SAAS;IACxD,OAAO;;GAER,iBAAiB,aAAa;IAC7B,KAAK,cAAcA,gCAAe,cAAc,SAAS;IACzD,OAAO;;GAER,kBAAkB,aAAa;IAC9B,KAAK,eAAeA,gCAAe,cAAc,SAAS;IAC1D,OAAO;;GAGR,cAAc,aAAa;IAC1B,KAAK,aAAaA,gCAAe,YAAY,SAAS;IACtD,OAAO;;GAER,eAAe,aAAa;IAC3B,KAAK,cAAcA,gCAAe,YAAY,SAAS;IACvD,OAAO;;GAER,gBAAgB,aAAa;IAC5B,KAAK,eAAeA,gCAAe,YAAY,SAAS;IACxD,OAAO;;GAGR,YAAY,aAAa;IACxB,KAAK,aAAaA,gCAAe,SAAS,SAAS;IACnD,OAAO;;GAER,aAAa,aAAa;IACzB,KAAK,cAAcA,gCAAe,SAAS,SAAS;IACpD,OAAO;;GAER,cAAc,aAAa;IAC1B,KAAK,eAAeA,gCAAe,SAAS,SAAS;IACrD,OAAO;;GAGR,UAAU,aAAa;IACtB,KAAK,aAAaA,gCAAe,OAAO,SAAS;IACjD,OAAO;;GAER,WAAW,aAAa;IACvB,KAAK,cAAcA,gCAAe,OAAO,SAAS;IAClD,OAAO;;GAER,YAAY,aAAa;IACxB,KAAK,eAAeA,gCAAe,OAAO,SAAS;IACnD,OAAO;;GAGR,UAAU,aAAa;IACtB,KAAK,aAAaA,gCAAe,OAAO,SAAS;IACjD,OAAO;;GAER,WAAW,aAAa;IACvB,KAAK,cAAcA,gCAAe,OAAO,SAAS;IAClD,OAAO;;GAER,YAAY,aAAa;IACxB,KAAK,eAAeA,gCAAe,OAAO,SAAS;IACnD,OAAO;;GAER;EAED,KAAK,YAAY;EAEjB,MAAM,iBAAqD;GAC1D,SAAS,aAAa;IACrB,KAAK,aAAaA,gCAAe,WAAW,SAAS;IACrD,OAAO;;GAER,UAAU,aAAa;IACtB,KAAK,cAAcA,gCAAe,WAAW,SAAS;IACtD,OAAO;;GAER,WAAW,aAAa;IACvB,KAAK,eAAeA,gCAAe,WAAW,SAAS;IACvD,OAAO;;GAGR,UAAU,aAAa;IACtB,KAAK,aAAaA,gCAAe,YAAY,SAAS;IACtD,OAAO;;GAER,WAAW,aAAa;IACvB,KAAK,cAAcA,gCAAe,YAAY,SAAS;IACvD,OAAO;;GAER,YAAY,aAAa;IACxB,KAAK,eAAeA,gCAAe,YAAY,SAAS;IACxD,OAAO;;GAER;EAED,MAAM,qBAA6D;GAClE,SAAS,aAAa;IACrB,KAAK,aAAaA,gCAAe,YAAY,SAAS;IACtD,OAAO;;GAER,UAAU,aAAa;IACtB,KAAK,cAAcA,gCAAe,YAAY,SAAS;IACvD,OAAO;;GAER,WAAW,aAAa;IACvB,KAAK,eAAeA,gCAAe,YAAY,SAAS;IACxD,OAAO;;GAGR,UAAU,aAAa;IACtB,KAAK,aAAaA,gCAAe,aAAa,SAAS;IACvD,OAAO;;GAER,WAAW,aAAa;IACvB,KAAK,cAAcA,gCAAe,aAAa,SAAS;IACxD,OAAO;;GAER,YAAY,aAAa;IACxB,KAAK,eAAeA,gCAAe,aAAa,SAAS;IACzD,OAAO;;GAER;EAED,KAAK,QAAQ;GACZ,YAAY,KAAK,WAAW,KAAK,KAAK;GACtC,MAAM,KAAKC,SAAS,KAAK,KAAK;GAC9B,IAAI,KAAKC,QAAQ,KAAK,KAAK;GAC3B,KAAK,KAAKC,SAAS,KAAK,KAAK;GAC7B,MAAM,KAAKC,UAAU,KAAK,KAAK;GAC/B,WAAW;GACX,MAAM;IACL,MAAM,KAAKC,aAAa,KAAK,KAAK;IAClC,WAAW;IACX;GACD;;CAQF,AAAU,WAAiB;EAC1B,KAAKC,aAAa;EAElB,KAAK,MAAM,UAAU,KAAK,QAAQ,QAAQ,EACzC,IAAI,CAAC,OAAO,UACX,OAAO,MAAM,MAAM,iBAAiB;EAGtC,KAAK,QAAQ,OAAO;EAEpB,KAAK,iBAAiB;EACtB,KAAKC,eAAe,EAAE;;CAGvB,KAA6F,OAAU,MAAe;EACrH,IAAI,KAAKD,YACR,OAAO;EAER,MAAM,UAAU,KAAK,OAAO;GAAE;GAAO;GAAM,CAAC;EAC5C,KAAK,WAAW,KAAK,QAAQ,eAAe,QAAQ;EACpD,OAAO;;CAGR,SAIE,MAAS,OAAU,MAA4B;EAChD,IAAI,KAAKA,YACR,OAAO,KAAK;EAEb,MAAM,UAAU,KAAK,OAAO;GAAE;GAAM;GAAO;GAAM,CAAC;EAClD,KAAK,WAAW,MAAM,QAAQ;EAC9B,OAAO,KAAK;;CAGb,aAIE,OAAW,OAAU,MAAiC;EACvD,IAAI,KAAKA,YACR,OAAO,KAAK,MAAM;EAEnB,MAAM,UAAU,KAAK,OAAO;GAAE;GAAO;GAAO;GAAM,CAAC;EACnD,KAAK,MAAM,QAAQ,OAClB,KAAK,WAAW,MAAM,QAAQ;EAE/B,OAAO,KAAK,MAAM;;CAGnB,GACC,OACA,UACO;EACP,KAAK,IAAI,OAAO,SAAS;EACzB,OAAO;;CAGR,IACC,OACA,UACO;EACP,KAAK,KAAK,OAAO,SAAS;EAC1B,OAAO;;CAGR,KACC,OACA,UACO;EACP,KAAK,MAAM,OAAO,SAAS;EAC3B,OAAO;;CAGR,QAIE,MAAS,OAAU,UAAkE;EACtF,KAAK,QAAQ,MAAM,OAAO,SAAS;EACnC,OAAO,KAAK;;CAGb,SAIE,MAAS,OAAW,UAAmE;EACxF,KAAK,SAAS,MAAM,OAAO,SAAS;EACpC,OAAO,KAAK;;CAGb,UAIE,MAAS,OAAU,UAAkE;EACtF,KAAK,UAAU,MAAM,OAAO,SAAS;EACrC,OAAO,KAAK;;CAGb,IAAI,IAAmC;EACtC,KAAKC,aAAa,KAAK,GAAG;EAC1B,OAAO;;CAGR,eAAe,OAA+C;EAC7D,OAAO,CAAC,CAAC,SAAS,OAAQ,MAA+B,SAAS;;CAGnE,gBACC,QACA,KACA,eACO;EACP,IAAI,QAAQ;EACZ,IAAI,UAAU;EAEd,MAAM,QAAQ,MAAM,KAAK,KAAKA,aAAa;EAE3C,MAAM,QAAwB,UAAU;GACvC,IAAI,SACH;GAED,IAAI,OAAO;IACV,UAAU;IACV,MAAM,YAAY,iBAAiB,SAAS,MAAM,SAAS;IAC3D,MAAM,QAAQ,YAAY,sBAAsB;IAChD,KAAK,kBAAkB,KAAK,uBAAuB,IAAIP,gCAAe,MAAM,EAAE,QAAQ;KAAE;KAAO;KAAO,CAAC;IAEvG,MAAM,SAAS,YAAY,KAAK,QAAQ,sBAAsB,KAAK,QAAQ;IAC3E,IAAI,WAAW,SACd,OAAO,MAAM,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,CAAC;SACpE,IAAI,OAAO,WAAW,YAC5B,OAAO,OAAO,OAAO;IAEtB;;GAGD,IAAI,SAAS,MAAM,QAClB,IAAI;IACH,OAAO,eAAe;YACd,KAAK;IACb,KAAK,kBAAkB,KAAK,uBAAuB,IAAIA,gCAAe,MAAM,EAAE,QAAQ;KAAE,OAAO;KAAiB,OAAO;KAAK,CAAC;IAC7H;;GAIF,MAAM,aAAa,MAAM;GACzB,IAAI,SAAS;GACb,IAAI,YAAkD;GAwCtD,MAAM,QAAyB,CAAC,IAtCV,SAAe,SAAS,WAAW;IACxD,IAAI;KACH,MAAM,SAAS,WAAW,QAAQ,MAAM,QAAQ;MAC/C,IAAI,QACH;MAED,SAAS;MACT,IAAI,KACH,OAAO,IAAI;WAEX,SAAS;OAET;KAEF,IAAI,KAAKQ,eAAe,OAAO,EAC9B,OAAO,WACA;MACL,IAAI,CAAC,QAAQ;OACZ,SAAS;OACT,SAAS;;SAGV,QAAQ;MACR,IAAI,CAAC,QAAQ;OACZ,SAAS;OACT,OAAO,IAAI;;OAGb;aAEM,SAAS;KACjB,IAAI,CAAC,QAAQ;MACZ,SAAS;MACT,OAAO,QAAQ;;;KAKuB,CAAC;GAE1C,IAAI,KAAK,QAAQ,oBAAoB,GAAG;IACvC,MAAM,UAAU,IAAI,SAAe,GAAG,WAAW;KAChD,YAAY,iBAAiB;MAC5B,IAAI,CAAC,QAAQ;OACZ,SAAS;OACT,MAAM,+BAAe,IAAI,MAAM,4BAA4B,KAAK,QAAQ,kBAAkB,IAAI;OAC9F,aAAa,OAAO;OACpB,OAAO,aAAa;;QAEnB,KAAK,QAAQ,kBAAkB;MACjC;IACF,MAAM,KAAK,QAAQ;;GAGpB,QAAQ,KAAK,MAAM,CACjB,WAAW,MAAM,CAAC,CAClB,OAAO,QAAQ,KAAK,IAAI,CAAC,CACzB,cAAc;IACd,IAAI,WACH,aAAa,UAAU;KAEvB;;EAGJ,MAAM;;CAGP,IAAI,YAAqB;EACxB,OAAO,KAAKF;;CAGb,uBAAuB,SAA6B,UAA2B;EAC9E,IAAI,MAAM,QAAQ,QAAQ,EAAE;GAC3B,MAAM,QAAQ,QAAQ,QAAQ,GAAG,MAAM,IAAI,EAAE,QAAQ,EAAE;GACvD,OAAO,eAAe,QAAQ,OAAO,UAAU,MAAM;;EAEtD,IAAI,UAEH,OAAO,WADK,OAAO,SAAS,QAAQ,GAAG,QAAQ,SAAS,QAAQ,WAC1C;EAEvB,OAAO,OAAO,YAAY,WAAW,UAAU,IAAI,aAAa,CAAC,OAAO,QAAQ;;CAGjF,AAAU,QAAQ,QAA8B,SAA6B,UAAmB;EAC/F,KAAK,cAAc,KAAK,uBAAuB,IAAIN,gCAAe,QAAQ,EAAE;GAAC;GAAQ;GAAS;GAAS,GAAG,UAAU;GACnH,IAAI,SAAS,MACZ,KAAK,kBAAkB,KAAK,uBAAuB,IAAIA,gCAAe,MAAM,EAAE,QAAQ;IAAE,OAAO;IAAa;IAAO,CAAC;IAEpH;EAEF,IAAI,aAAa,QAAQ,eAAe,KAAM,mBAAmB,UAAU,QAAQ,WAAW,IAAK;GAClG,OAAO,QAAQ,IAAI,WAAW,EAAE,EAAE,KAAK;GACvC;;EAGD,IAAI;EACJ,IAAI;GACH,SAAS,KAAK,OAAO,SAAS,SAAS;WAC/B,OAAO;GACf,MAAM,MAAM,KAAKS,uBAAuB,SAAS,SAAS;GAC1D,KAAK,kBAAkB,KAAK,uBAAuB,IAAIT,gCAAe,MAAM,EAAE,QAAQ;IAAE,OAAO;IAAU;IAAK;IAAO,CAAC;GACtH,OAAO,MAAM,MAAM,eAAe;GAClC;;EAGD,IAAI,UAAU,QAAQ,OAAO,WAAW,UAAU;GACjD,MAAM,wBAAQ,IAAI,MAAM,4BAA4B;GACpD,KAAK,kBAAkB,KAAK,uBAAuB,IAAIA,gCAAe,MAAM,EAAE,QAAQ;IACrF,OAAO;IACP,KAAK,KAAK,UAAU,OAAO;IAC3B;IACA,CAAC;GACF,OAAO,MAAM,MAAM,aAAa;GAChC;;EAGD,IAAI,KAAKU,mBAAmB,QAAQ,OAAO,EAC1C;EAED,IAAI,CAAC,OAAO,iBACX;EAED,IAAI,KAAKC,uBAAuB,QAAQ,OAAO,EAC9C;EAED,IAAI,KAAKC,wBAAwB,QAAQ,OAAO,EAC/C;EAED,IAAI,KAAKC,wBAAwB,QAAQ,OAAO,EAC/C;EAED,IAAI,KAAKC,yBAAyB,QAAQ,OAAO,EAChD;EAED,KAAKC,gBAAgB,QAAQ,cAA6B;GACzD,IAAI,KAAKC,yBAAyB,QAAQ,OAAO,EAChD;GAED,IAAI,KAAKC,wBAAwB,QAAQ,OAAO,EAC/C;GAED,IAAI,KAAKC,oBAAoB,QAAQ,OAAO,EAC3C;IAEA;;CAGH,AAAU,MAAM,QAA8B,MAAc,QAA8B;EACzF,IAAI,KAAK,UAAU,SAAS,MAC3B,QAAQ,KAAK,2BAA2B,OAAO,KAAK;EAErD,KAAK,QAAQ,OAAO,OAAO,GAAG;EAC9B,OAAO,MAAM,MAAM,OAAO,KAAK,OAAsB,CAAC,SAAS,OAAO,CAAC;EACvE,KAAK,cAAc,KAAK,uBAAuB,IAAIlB,gCAAe,MAAM,EAAE;GAAC;GAAQ;GAAM;GAAO,GAAG,UAAU;GAC5G,IAAI,SAAS,MACZ,KAAK,kBAAkB,KAAK,uBAAuB,IAAIA,gCAAe,MAAM,EAAE,QAAQ;IAAE,OAAO;IAAW;IAAO,CAAC;IAElH;;CAGH,mBAAqC,QAA8B,QAAoB;EACtF,IAAI,CAAC,KAAK,2BAA2BA,gCAAe,MAAM,OAAO,EAChE,OAAO;EAER,OAAO,YAAY,QAAQ,KAAK,QAAQ,MAAM,KAAK,QAAQ,cAAc,QAAQ;GAChF,IAAI,OAAO,MAAM;IAChB,KAAK,cAAc,KAAK,uBAAuB,IAAIA,gCAAe,aAAa,EAAE,CAAC,OAAO,GAAG,UAAU;KACrG,IAAI,SAAS,MACZ,KAAK,kBAAkB,KAAK,uBAAuB,IAAIA,gCAAe,MAAM,EAAE,QAAQ;MAAE,OAAO;MAAiB;MAAO,CAAC;MAExH;IACF,KAAK,cAAc,KAAK,uBAAuB,IAAIA,gCAAe,KAAK,EAAE,CAAC,OAAO,GAAG,UAAU;KAC7F,IAAI,SAAS,MACZ,KAAK,kBAAkB,KAAK,uBAAuB,IAAIA,gCAAe,MAAM,EAAE,QAAQ;MAAE,OAAO;MAAU;MAAO,CAAC;MAEjH;UACI;IACN,MAAM,MAAoB;KACzB,OAAO;KACP,OAAO,eAAe,QAAQ,MAAM,IAAI,MAAM,OAAO,IAAI,CAAC;KAC1D,MAAM;KACN;IACD,KAAK,cAAc,KAAK,uBAAuB,IAAIA,gCAAe,WAAW,EAAE,CAAC,QAAQ,IAAI,GAAG,UAAU;KACxG,IAAI,SAAS,MACZ,KAAK,kBAAkB,KAAK,uBAAuB,IAAIA,gCAAe,MAAM,EAAE,QAAQ;MAAE,OAAO;MAAe;MAAO,CAAC;MAEtH;;IAEF;EACF,OAAO;;CAGR,uBAAyC,QAA8B,QAAoB;EAC1F,IAAI,CAAC,KAAK,wBAAwBA,gCAAe,WAAW,OAAO,EAClE,OAAO;EAER,KAAKmB,qBAAqB,KAAK,uBAAuB,IAAInB,gCAAe,UAAU,EAAE,CAAC,QAAQ,OAAO,KAAK,GAAG,UAAU;GACtH,IAAI,SAAS,MAAM;IAClB,OAAO,MAAM,KAAK,OAAO,KAAK;IAC9B,OAAO,KAAK;KAAE,MAAMA,gCAAe;KAAmB,MAAM,OAAO;KAAM,CAAC;UAE1E,OAAO,KAAK;IAAE,MAAMA,gCAAe;IAAiB,MAAM,OAAO;IAAM,MAAM;KAAE,OAAO;KAAc;KAAO;IAAE,CAAC;IAE9G;EACF,OAAO;;CAGR,wBAA0C,QAA8B,QAAoB;EAC3F,IAAI,CAAC,KAAK,wBAAwBA,gCAAe,YAAY,OAAO,EACnE,OAAO;EAER,KAAKmB,qBAAqB,KAAK,uBAAuB,IAAInB,gCAAe,WAAW,EAAE,CAAC,QAAQ,OAAO,KAAK,GAAG,UAAU;GACvH,IAAI,SAAS,MAAM;IAClB,OAAO,MAAM,MAAM,OAAO,KAAK;IAC/B,OAAO,KAAK;KAAE,MAAMA,gCAAe;KAAoB,MAAM,OAAO;KAAM,CAAC;UAE3E,OAAO,KAAK;IAAE,MAAMA,gCAAe;IAAkB,MAAM,OAAO;IAAM,MAAM;KAAE,OAAO;KAAe;KAAO;IAAE,CAAC;IAEhH;EACF,OAAO;;CAGR,wBAA0C,QAA8B,QAAoB;EAC3F,IAAI,CAAC,KAAK,yBAAyBA,gCAAe,YAAY,OAAO,EACpE,OAAO;EAER,KAAKmB,qBAAqB,KAAK,uBAAuB,IAAInB,gCAAe,WAAW,EAAE,CAAC,QAAQ,OAAO,MAAM,GAAG,UAAU;GACxH,IAAI,SAAS,MAAM;IAClB,OAAO,MAAM,KAAK,KAAK,OAAO,MAAM;IACpC,OAAO,KAAK;KAAE,MAAMA,gCAAe;KAAoB,OAAO,OAAO;KAAO,CAAC;UAE7E,OAAO,KAAK;IAAE,MAAMA,gCAAe;IAAkB,OAAO,OAAO;IAAO,MAAM;KAAE,OAAO;KAAe;KAAO;IAAE,CAAC;IAElH;EACF,OAAO;;CAGR,yBAA2C,QAA8B,QAAoB;EAC5F,IAAI,CAAC,KAAK,yBAAyBA,gCAAe,aAAa,OAAO,EACrE,OAAO;EAER,KAAKmB,qBAAqB,KAAK,uBAAuB,IAAInB,gCAAe,YAAY,EAAE,CAAC,QAAQ,OAAO,MAAM,GAAG,UAAU;GACzH,IAAI,SAAS,MAAM;IAClB,OAAO,MAAM,KAAK,MAAM,OAAO,MAAM;IACrC,OAAO,KAAK;KAAE,MAAMA,gCAAe;KAAqB,OAAO,OAAO;KAAO,CAAC;UAE9E,OAAO,KAAK;IAAE,MAAMA,gCAAe;IAAmB,OAAO,OAAO;IAAO,MAAM;KAAE,OAAO;KAAgB;KAAO;IAAE,CAAC;IAEpH;EACF,OAAO;;CAGR,yBAA2C,QAA8B,QAAoB;EAC5F,IAAI,CAAC,KAAK,qBAAqB,OAAO,EACrC,OAAO;EAER,MAAM,UAAU,KAAK,OAAO;GAAE,OAAO,OAAO;GAAO,OAAO,OAAO;GAAO,MAAM,OAAO;GAAM,CAAC;EAC5F,KAAK,MAAM,QAAQ,OAAO,OACzB,KAAKmB,qBAAqB,KAAK,kBAAkB,IAAI,KAAK,EAAE,IAAI,OAAO,MAAM,EAAE,CAAC,QAAQ,OAAO,KAAK,GAAG,UAAU;GAChH,IAAI,SAAS,MACZ,OAAO,MAAM,WAAW,MAAM,QAAQ;QAEtC,KAAK,kBAAkB,KAAK,uBAAuB,IAAInB,gCAAe,MAAM,EAAE,QAAQ;IACrF,OAAO;IACP,KAAK,KAAK,UAAU,OAAO;IAC3B;IACA,CAAC;IAEF;EAEH,OAAO;;CAGR,wBAA0C,QAA8B,QAAoB;EAC3F,IAAI,CAAC,KAAK,oBAAoB,OAAO,EACpC,OAAO;EAER,KAAKmB,qBAAqB,KAAK,kBAAkB,IAAI,OAAO,KAAK,EAAE,IAAI,OAAO,MAAM,EAAE,CAAC,QAAQ,OAAO,KAAK,GAAG,UAAU;GACvH,IAAI,SAAS,MAAM;IAClB,MAAM,UAAU,KAAK,OAAO;KAAE,MAAM,OAAO;KAAM,OAAO,OAAO;KAAO,MAAM,OAAO;KAAM,CAAC;IAC1F,OAAO,MAAM,WAAW,OAAO,MAAM,QAAQ;UAE7C,KAAK,kBAAkB,KAAK,uBAAuB,IAAInB,gCAAe,MAAM,EAAE,QAAQ;IACrF,OAAO;IACP,KAAK,KAAK,UAAU,OAAO;IAC3B;IACA,CAAC;IAEF;EACF,OAAO;;CAGR,oBAAsC,QAA8B,QAAoB;EACvF,IAAI,CAAC,KAAK,gBAAgB,OAAO,EAChC,OAAO;EAER,KAAK,kBAAkB,KAAK,cAAc,IAAI,OAAO,MAAM,EAAE,QAAQ,OAAO,KAAK;EACjF,OAAO;;CAGR,AAAU,cAA2C,aAA2C,MAAY,MAA4B;EACvI,IAAI,CAAC,aACJ,OAAO,MAAM;EAEd,IAAI,aAAsB;EAC1B,KAAK,MAAM,YAAY,aACtB,IAAI;GACH,SAAS,GAAG,KAAK;WACT,KAAK;GACb,IAAI,KAAK,QACR,QAAQ,MAAM,IAAI;GAEnB,aAAa,cAAc;;EAG7B,KAAK,WAAW;;CAGjB,qBAAkD,WAAyC,MAAY,eAAqC;EAC3I,IAAI,CAAC,aAAa,UAAU,SAAS,GAAG;GACvC,IAAI;IACH,eAAe;YACP,KAAK;IACb,MAAM,SAAS,KAAK,cAAc,mBAAmB,KAAK,KAAK;IAC/D,KAAK,kBAAkB,KAAK,uBAAuB,IAAIA,gCAAe,MAAM,EAAE,QAAQ;KAAE,OAAO;KAAkB,OAAO;KAAK,CAAC;;GAE/H;;EAGD,MAAM,QAAQ,MAAM,KAAK,UAAU;EACnC,IAAI,QAAQ;EAEZ,MAAM,QAAwB,UAAU;GACvC,IAAI,OACH,OAAO,cAAc,MAAM;GAE5B,IAAI,SAAS,MAAM,QAClB,IAAI;IACH,OAAO,eAAe;YACd,KAAK;IACb,MAAM,SAAS,KAAK,cAAc,mBAAmB,KAAK,KAAK;IAC/D,KAAK,kBAAkB,KAAK,uBAAuB,IAAIA,gCAAe,MAAM,EAAE,QAAQ;KAAE,OAAO;KAAkB,OAAO;KAAK,CAAC;IAC9H;;GAIF,MAAM,WAAW,MAAM;GACvB,IAAI,SAAS;GACb,IAAI,YAAkD;GAwCtD,MAAM,QAAyB,CAAC,IAtCV,SAAe,SAAS,WAAW;IACxD,IAAI;KACH,MAAM,SAAS,SAAS,GAAG,OAAO,QAAkB;MACnD,IAAI,QACH;MAED,SAAS;MACT,IAAI,KACH,OAAO,IAAI;WAEX,SAAS;OAET;KAEF,IAAI,KAAKQ,eAAe,OAAO,EAC9B,OAAO,WACA;MACL,IAAI,CAAC,QAAQ;OACZ,SAAS;OACT,SAAS;;SAGV,QAAQ;MACR,IAAI,CAAC,QAAQ;OACZ,SAAS;OACT,OAAO,IAAI;;OAGb;aAEM,SAAS;KACjB,IAAI,CAAC,QAAQ;MACZ,SAAS;MACT,OAAO,QAAQ;;;KAKuB,CAAC;GAE1C,IAAI,KAAK,QAAQ,wBAAwB,GAAG;IAC3C,MAAM,UAAU,IAAI,SAAe,GAAG,WAAW;KAChD,YAAY,iBAAiB;MAC5B,IAAI,CAAC,QAAQ;OACZ,SAAS;OACT,MAAM,+BAAe,IAAI,MAAM,iCAAiC,KAAK,QAAQ,sBAAsB,IAAI;OACvG,aAAa,OAAO;OACpB,OAAO,aAAa;;QAEnB,KAAK,QAAQ,sBAAsB;MACrC;IACF,MAAM,KAAK,QAAQ;;GAGpB,QAAQ,KAAK,MAAM,CACjB,WAAW,MAAM,CAAC,CAClB,OAAO,QAAQ,KAAK,IAAI,CAAC,CACzB,cAAc;IACd,IAAI,WACH,aAAa,UAAU;KAEvB;;EAGJ,MAAM"}

@@ -1,2 +0,2 @@

import { _ as RoomEventMiddleware, a as IRoomsBulkServer, b as SocketData, c as ISocket, d as AuthCallback, f as AuthFunction, g as MiddlewareNext, h as Middleware, i as IRoomsBulkLifecycleServer, l as ISocketRooms, m as EventCallback, n as IByteSocket, o as IRoomsLifecycleServer, p as ByteSocketOptionsBase, r as ILifecycleServer, s as IRoomsServer, t as ByteSocketServerBase, u as ISocketRoomsBulk, v as ServerIncomingData, y as ServerOutgoingData } from "./byte-socket-server-base-CLZDN4De.cjs";
import { _ as RoomEventMiddleware, a as IRoomsBulkServer, b as SocketData, c as ISocket, d as AuthCallback, f as AuthFunction, g as MiddlewareNext, h as Middleware, i as IRoomsBulkLifecycleServer, l as ISocketRooms, m as EventCallback, n as IByteSocket, o as IRoomsLifecycleServer, p as ByteSocketOptionsBase, r as ILifecycleServer, s as IRoomsServer, t as ByteSocketServerBase, u as ISocketRoomsBulk, v as ServerIncomingData, y as ServerOutgoingData } from "./byte-socket-server-base-Cri0yUAN.cjs";
import { LifecycleMessage, LifecycleTypes, SocketEvents, StringNumberKeys, UserMessage } from "@bytesocket/core";

@@ -3,0 +3,0 @@ export * from "@bytesocket/core";

@@ -1,2 +0,2 @@

import { _ as RoomEventMiddleware, a as IRoomsBulkServer, b as SocketData, c as ISocket, d as AuthCallback, f as AuthFunction, g as MiddlewareNext, h as Middleware, i as IRoomsBulkLifecycleServer, l as ISocketRooms, m as EventCallback, n as IByteSocket, o as IRoomsLifecycleServer, p as ByteSocketOptionsBase, r as ILifecycleServer, s as IRoomsServer, t as ByteSocketServerBase, u as ISocketRoomsBulk, v as ServerIncomingData, y as ServerOutgoingData } from "./byte-socket-server-base-DFXqLJh0.js";
import { _ as RoomEventMiddleware, a as IRoomsBulkServer, b as SocketData, c as ISocket, d as AuthCallback, f as AuthFunction, g as MiddlewareNext, h as Middleware, i as IRoomsBulkLifecycleServer, l as ISocketRooms, m as EventCallback, n as IByteSocket, o as IRoomsLifecycleServer, p as ByteSocketOptionsBase, r as ILifecycleServer, s as IRoomsServer, t as ByteSocketServerBase, u as ISocketRoomsBulk, v as ServerIncomingData, y as ServerOutgoingData } from "./byte-socket-server-base-3oCYTtHD.js";
import { LifecycleMessage, LifecycleTypes, SocketEvents, StringNumberKeys, UserMessage } from "@bytesocket/core";

@@ -3,0 +3,0 @@ export * from "@bytesocket/core";

@@ -130,3 +130,3 @@ import { AuthState, ByteSocketBase, LifecycleTypes } from "@bytesocket/core";

this.#authState = AuthState.pending;
this.#authTimer = setTimeout(() => {
if (authTimeout > 0) this.#authTimer = setTimeout(() => {
if (!this.isClosed && !this.isAuthenticated) {

@@ -216,9 +216,9 @@ const err = /* @__PURE__ */ new Error("Auth timeout");

...options,
middlewareTimeout: options.middlewareTimeout ?? 5e3,
roomMiddlewareTimeout: options.roomMiddlewareTimeout ?? 5e3,
authTimeout: options.authTimeout ?? 5e3,
middlewareTimeout: options.middlewareTimeout ?? 0,
roomMiddlewareTimeout: options.roomMiddlewareTimeout ?? 0,
authTimeout: options.authTimeout ?? 0,
broadcastRoom: options.broadcastRoom ?? "__bytesocket_broadcast__",
onMiddlewareError: options.onMiddlewareError ?? "ignore",
onMiddlewareTimeout: options.onMiddlewareTimeout ?? "ignore",
idleTimeout: options.idleTimeout ?? 120,
idleTimeout: options.idleTimeout ?? 12e4,
sendPingsAutomatically: options.sendPingsAutomatically ?? true

@@ -442,2 +442,5 @@ };

}
#isPromiseLike(value) {
return !!value && typeof value.then === "function";
}
#runMiddlewares(socket, ctx, finalCallback) {

@@ -474,3 +477,3 @@ let index = 0;

let timeoutId = null;
const execution = new Promise((resolve, reject) => {
const tasks = [new Promise((resolve, reject) => {
try {

@@ -483,3 +486,3 @@ const result = middleware(socket, ctx, (err) => {

});
if (result instanceof Promise) result.then(() => {
if (this.#isPromiseLike(result)) result.then(() => {
if (!called) {

@@ -501,14 +504,17 @@ called = true;

}
});
const timeout = new Promise((_, reject) => {
timeoutId = setTimeout(() => {
if (!called) {
called = true;
const timeoutError = /* @__PURE__ */ new Error(`Middleware timeout after ${this.options.middlewareTimeout}ms`);
timeoutError.name = "TimeoutError";
reject(timeoutError);
}
}, this.options.middlewareTimeout);
});
Promise.race([execution, timeout]).then(() => next()).catch((err) => next(err)).finally(() => {
})];
if (this.options.middlewareTimeout > 0) {
const timeout = new Promise((_, reject) => {
timeoutId = setTimeout(() => {
if (!called) {
called = true;
const timeoutError = /* @__PURE__ */ new Error(`Middleware timeout after ${this.options.middlewareTimeout}ms`);
timeoutError.name = "TimeoutError";
reject(timeoutError);
}
}, this.options.middlewareTimeout);
});
tasks.push(timeout);
}
Promise.race(tasks).then(() => next()).catch((err) => next(err)).finally(() => {
if (timeoutId) clearTimeout(timeoutId);

@@ -788,3 +794,3 @@ });

let timeoutId = null;
const execution = new Promise((resolve, reject) => {
const tasks = [new Promise((resolve, reject) => {
try {

@@ -797,3 +803,3 @@ const result = callback(...args, (err) => {

});
if (result instanceof Promise) result.then(() => {
if (this.#isPromiseLike(result)) result.then(() => {
if (!called) {

@@ -815,14 +821,17 @@ called = true;

}
});
const timeout = new Promise((_, reject) => {
timeoutId = setTimeout(() => {
if (!called) {
called = true;
const timeoutError = /* @__PURE__ */ new Error(`Room middleware timeout after ${this.options.roomMiddlewareTimeout}ms`);
timeoutError.name = "TimeoutError";
reject(timeoutError);
}
}, this.options.roomMiddlewareTimeout);
});
Promise.race([execution, timeout]).then(() => next()).catch((err) => next(err)).finally(() => {
})];
if (this.options.roomMiddlewareTimeout > 0) {
const timeout = new Promise((_, reject) => {
timeoutId = setTimeout(() => {
if (!called) {
called = true;
const timeoutError = /* @__PURE__ */ new Error(`Room middleware timeout after ${this.options.roomMiddlewareTimeout}ms`);
timeoutError.name = "TimeoutError";
reject(timeoutError);
}
}, this.options.roomMiddlewareTimeout);
});
tasks.push(timeout);
}
Promise.race(tasks).then(() => next()).catch((err) => next(err)).finally(() => {
if (timeoutId) clearTimeout(timeoutId);

@@ -829,0 +838,0 @@ });

@@ -1,1 +0,1 @@

{"version":3,"file":"index.js","names":["#authState","#closed","#encode","#publish","#publishMany","#joinRooms","#leaveRooms","#clearAuthTimer","#authTimer","#setAuthFailed","#setAuthSuccess","#handleNoAuth","#sendUnchecked","#publish","#onRoom","#offRoom","#onceRoom","#publishMany","#destroyed","#middlewares","#rawMessageDescription","#handleAuthMessage","#handleJoinRoomMessage","#handleLeaveRoomMessage","#handleJoinRoomsMessage","#handleLeaveRoomsMessage","#runMiddlewares","#handleRoomsEventMessage","#handleRoomEventMessage","#handleEventMessage","#runAsyncHooksOrNext"],"sources":["../src/socket-server-base.ts","../src/byte-socket-server-base.ts"],"sourcesContent":["// packages/server/src/socket-server-base.ts\nimport {\n\tAuthState,\n\tLifecycleTypes,\n\ttype ErrorContext,\n\ttype EventsForRooms,\n\ttype LifecycleMessage,\n\ttype SocketEvents,\n\ttype StringKeys,\n\ttype StringNumberKeys,\n\ttype UserMessage,\n} from \"@bytesocket/core\";\nimport type { ISocket, ISocketRooms } from \"./interfaces\";\nimport type { AuthFunction, MiddlewareNext, ServerOutgoingData, SocketData } from \"./types\";\n\nexport abstract class SocketServerBase<TEvents extends SocketEvents = SocketEvents, SD extends SocketData = SocketData> implements ISocket<\n\tTEvents,\n\tSD\n> {\n\treadonly rooms: ISocketRooms<TEvents>;\n\n\tpayload: any = {};\n\tlocals: any = {};\n\n\t#encode: <R extends string, E extends string | number, D>(\n\t\tpayload: LifecycleMessage<R, D> | UserMessage<R, E, D>,\n\t) => string | Buffer<ArrayBufferLike>;\n\t#authState: AuthState = AuthState.idle;\n\t#authTimer: ReturnType<typeof setTimeout> | null = null;\n\t#closed: boolean = false;\n\n\tget isAuthenticated(): boolean {\n\t\treturn this.#authState === AuthState.none || this.#authState === AuthState.success;\n\t}\n\tget isClosed(): boolean {\n\t\treturn this.#closed;\n\t}\n\tget canSend(): boolean {\n\t\treturn !this.#closed && this.isAuthenticated;\n\t}\n\n\tabstract readonly userData: SD;\n\tget id(): string {\n\t\treturn this.userData.socketKey;\n\t}\n\tget url(): string {\n\t\treturn this.userData.url;\n\t}\n\tget query(): string {\n\t\treturn this.userData.query;\n\t}\n\tget cookie(): string {\n\t\treturn this.userData.cookie;\n\t}\n\tget authorization(): string {\n\t\treturn this.userData.authorization;\n\t}\n\tget userAgent(): string {\n\t\treturn this.userData.userAgent;\n\t}\n\tget host(): string {\n\t\treturn this.userData.host;\n\t}\n\tget xForwardedFor(): string {\n\t\treturn this.userData.xForwardedFor;\n\t}\n\n\tprotected abstract readonly broadcastRoom: string;\n\n\tconstructor(\n\t\tencode: <R extends string, E extends string | number, D>(\n\t\t\tpayload: LifecycleMessage<R, D> | UserMessage<R, E, D>,\n\t\t) => string | Buffer<ArrayBufferLike>,\n\t) {\n\t\tthis.#encode = encode;\n\t\tthis.rooms = {\n\t\t\tpublishRaw: this.publishRaw.bind(this),\n\t\t\temit: this.#publish.bind(this),\n\t\t\tjoin: this.joinRoom.bind(this),\n\t\t\tleave: this.leaveRoom.bind(this),\n\t\t\tlist: this.getRoomList.bind(this),\n\t\t\tbulk: {\n\t\t\t\temit: this.#publishMany.bind(this),\n\t\t\t\tjoin: this.#joinRooms.bind(this),\n\t\t\t\tleave: this.#leaveRooms.bind(this),\n\t\t\t},\n\t\t};\n\t}\n\n\tabstract sendRaw(message: ServerOutgoingData, isBinary?: boolean, compress?: boolean): this;\n\n\tprotected abstract getRoomList(includeBroadcast?: boolean): string[];\n\n\tprotected abstract publishRaw(room: string, message: ServerOutgoingData, isBinary?: boolean, compress?: boolean): typeof this.rooms;\n\n\tprotected abstract joinRoom(room: string): typeof this.rooms;\n\n\tprotected abstract leaveRoom(room: string): typeof this.rooms;\n\n\tabstract close(code?: number, reason?: string): void;\n\n\tprotected startHeartbeat(): void {}\n\n\tprotected clearHeartbeat(): void {}\n\n\temit<E extends StringNumberKeys<TEvents[\"emit\"]>, D extends NonNullable<TEvents[\"emit\"]>[E]>(event: E, data: D): this {\n\t\tthis.send({ event, data });\n\t\treturn this;\n\t}\n\n\tsend<R extends string, E extends string | number, D>(payload: LifecycleMessage<R, D> | UserMessage<R, E, D>): this {\n\t\tif (!this.canSend) {\n\t\t\treturn this;\n\t\t}\n\t\tconst message = this.#encode(payload);\n\t\tthis.sendRaw(message);\n\t\treturn this;\n\t}\n\n\tbroadcast<E extends StringNumberKeys<TEvents[\"emit\"]>, D extends NonNullable<TEvents[\"emit\"]>[E]>(event: E, data: D): this {\n\t\tif (!this.canSend) {\n\t\t\treturn this;\n\t\t}\n\t\tconst message = this.#encode({ event, data });\n\t\tthis.publishRaw(this.broadcastRoom, message);\n\t\treturn this;\n\t}\n\n\t#sendUnchecked<R extends string, E extends string | number, D>(payload: LifecycleMessage<R, D> | UserMessage<R, E, D>): void {\n\t\tif (this.#closed) {\n\t\t\treturn;\n\t\t}\n\t\tconst message = this.#encode(payload);\n\t\tthis.sendRaw(message);\n\t}\n\n\t#publish<\n\t\tR extends StringKeys<TEvents[\"emitRoom\"]>,\n\t\tE extends StringNumberKeys<NonNullable<TEvents[\"emitRoom\"]>[R]>,\n\t\tD extends NonNullable<TEvents[\"emitRoom\"]>[R][E],\n\t>(room: R, event: E, data: D): typeof this.rooms {\n\t\tif (!this.canSend) {\n\t\t\treturn this.rooms;\n\t\t}\n\t\tconst message = this.#encode({ room, event, data });\n\t\tthis.publishRaw(room, message);\n\t\treturn this.rooms;\n\t}\n\n\t#publishMany<\n\t\tRs extends NonNullable<TEvents[\"emitRooms\"]>[\"rooms\"],\n\t\tE extends StringNumberKeys<EventsForRooms<NonNullable<TEvents[\"emitRooms\"]>, Rs>>,\n\t\tD extends NonNullable<EventsForRooms<NonNullable<TEvents[\"emitRooms\"]>, Rs>>[E],\n\t>(rooms: Rs, event: E, data: D): typeof this.rooms.bulk {\n\t\tif (!this.canSend) {\n\t\t\treturn this.rooms.bulk;\n\t\t}\n\t\tconst message = this.#encode({ rooms, event, data });\n\t\tfor (const room of rooms) {\n\t\t\tthis.publishRaw(room, message);\n\t\t}\n\t\treturn this.rooms.bulk;\n\t}\n\n\t#joinRooms(rooms: string[]): typeof this.rooms.bulk {\n\t\tif (!this.canSend) {\n\t\t\treturn this.rooms.bulk;\n\t\t}\n\t\tfor (const room of rooms) {\n\t\t\tthis.joinRoom(room);\n\t\t}\n\t\treturn this.rooms.bulk;\n\t}\n\n\t#leaveRooms(rooms: string[]): typeof this.rooms.bulk {\n\t\tif (!this.canSend) {\n\t\t\treturn this.rooms.bulk;\n\t\t}\n\t\tfor (const room of rooms) {\n\t\t\tthis.leaveRoom(room);\n\t\t}\n\t\treturn this.rooms.bulk;\n\t}\n\n\tprotected _close(): void {\n\t\tthis.#closed = true;\n\t\tthis.#clearAuthTimer();\n\t\tthis.clearHeartbeat();\n\t}\n\n\t_handleAuth<D>(\n\t\tparsed: { type: LifecycleTypes.auth; data: D } | null,\n\t\tauth: AuthFunction<TEvents, SD, D> | undefined,\n\t\tauthTimeout: number,\n\t\tnext: MiddlewareNext,\n\t) {\n\t\tif (auth && parsed !== null) {\n\t\t\tif (this.#authState !== AuthState.idle) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.#authState = AuthState.pending;\n\t\t\tthis.#authTimer = setTimeout(() => {\n\t\t\t\tif (!this.isClosed && !this.isAuthenticated) {\n\t\t\t\t\tconst err = new Error(\"Auth timeout\");\n\t\t\t\t\tthis.#setAuthFailed({ phase: \"auth\", error: err, code: 4008 });\n\t\t\t\t\tnext(err);\n\t\t\t\t}\n\t\t\t}, authTimeout);\n\t\t\ttry {\n\t\t\t\tauth(this, parsed.data, (payload, error) => {\n\t\t\t\t\tif (error) {\n\t\t\t\t\t\tconst err = error || new Error(\"Auth failed\");\n\t\t\t\t\t\tthis.#setAuthFailed({ phase: \"auth\", error: err, code: 4003 });\n\t\t\t\t\t\tnext(err);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tthis.#setAuthSuccess(payload);\n\t\t\t\t\tthis.rooms.join(this.broadcastRoom);\n\t\t\t\t\tthis.startHeartbeat();\n\t\t\t\t\tnext();\n\t\t\t\t});\n\t\t\t} catch (err) {\n\t\t\t\tthis.#setAuthFailed({ phase: \"auth\", error: err, code: 4003 });\n\t\t\t\tnext(err);\n\t\t\t}\n\t\t} else {\n\t\t\tthis.#handleNoAuth();\n\t\t\tthis.startHeartbeat();\n\t\t\tnext();\n\t\t}\n\t}\n\n\t#handleNoAuth() {\n\t\tif (this.#closed || this.#authState !== AuthState.idle) {\n\t\t\treturn;\n\t\t}\n\t\tthis.#authState = AuthState.none;\n\t\tthis.rooms.join(this.broadcastRoom);\n\t}\n\n\t#setAuthSuccess<P>(payload: P): void {\n\t\tif (this.#closed || this.#authState !== AuthState.pending) {\n\t\t\treturn;\n\t\t}\n\t\tthis.#clearAuthTimer();\n\t\tthis.#authState = AuthState.success;\n\t\tthis.payload = payload;\n\t\tthis.#sendUnchecked({ type: LifecycleTypes.auth_success });\n\t}\n\n\t#setAuthFailed(ctx: ErrorContext): void {\n\t\tif (this.#closed || this.#authState !== AuthState.pending) {\n\t\t\treturn;\n\t\t}\n\t\tthis.#clearAuthTimer();\n\t\tthis.#authState = AuthState.failed;\n\t\tthis.#sendUnchecked({ type: LifecycleTypes.auth_error, data: ctx });\n\t\tthis.close(ctx.code, ctx.phase);\n\t}\n\n\t#clearAuthTimer(): void {\n\t\tif (this.#authTimer) {\n\t\t\tclearTimeout(this.#authTimer);\n\t\t\tthis.#authTimer = null;\n\t\t}\n\t}\n}\n","// packages/server/src/byte-socket-server-base.ts\nimport {\n\tByteSocketBase,\n\tLifecycleTypes,\n\ttype AnyCallback,\n\ttype ErrorContext,\n\ttype EventsForRooms,\n\ttype SocketEvents,\n\ttype StringKeys,\n\ttype StringNumberKeys,\n\ttype UserMessage,\n} from \"@bytesocket/core\";\nimport type { IByteSocket, ILifecycleServer, IRoomsBulkLifecycleServer, IRoomsLifecycleServer, IRoomsServer, ISocket } from \"./interfaces\";\nimport { SocketServerBase } from \"./socket-server-base\";\nimport type {\n\tByteSocketOptionsBase,\n\tEventCallback,\n\tMiddleware,\n\tMiddlewareNext,\n\tRoomEventMiddleware,\n\tServerIncomingData,\n\tServerOutgoingData,\n\tSocketData,\n} from \"./types\";\n\ntype RequiredOptions =\n\t| \"middlewareTimeout\"\n\t| \"roomMiddlewareTimeout\"\n\t| \"authTimeout\"\n\t| \"broadcastRoom\"\n\t| \"onMiddlewareError\"\n\t| \"onMiddlewareTimeout\"\n\t| \"idleTimeout\"\n\t| \"sendPingsAutomatically\";\n\nexport abstract class ByteSocketServerBase<\n\tTEvents extends SocketEvents = SocketEvents,\n\tSD extends SocketData = SocketData,\n\tUpgradeCallback extends AnyCallback = AnyCallback,\n>\n\textends ByteSocketBase\n\timplements IByteSocket<TEvents, SD, UpgradeCallback>\n{\n\t// ──── Namespaces ────────────────────────────────────────────────────────────────────────\n\treadonly lifecycle: ILifecycleServer<TEvents, SD, UpgradeCallback>;\n\treadonly rooms: IRoomsServer<TEvents, SD>;\n\treadonly sockets = new Map<string, ISocket<TEvents, SD>>();\n\n\t// ──── States ────────────────────────────────────────────────────────────────────────\n\n\tprotected options: Omit<ByteSocketOptionsBase<TEvents, SD>, RequiredOptions | \"debug\" | \"serialization\" | \"msgpackrOptions\"> &\n\t\tPick<Required<ByteSocketOptionsBase<TEvents, SD>>, RequiredOptions>;\n\t#middlewares: Middleware<TEvents, SD>[] = [];\n\t#destroyed = false;\n\n\tconstructor(options: ByteSocketOptionsBase<TEvents, SD> = {}) {\n\t\tsuper(options);\n\n\t\tthis.options = {\n\t\t\t...options,\n\t\t\tmiddlewareTimeout: options.middlewareTimeout ?? 5000,\n\t\t\troomMiddlewareTimeout: options.roomMiddlewareTimeout ?? 5000,\n\t\t\tauthTimeout: options.authTimeout ?? 5000,\n\t\t\tbroadcastRoom: options.broadcastRoom ?? \"__bytesocket_broadcast__\",\n\t\t\tonMiddlewareError: options.onMiddlewareError ?? \"ignore\",\n\t\t\tonMiddlewareTimeout: options.onMiddlewareTimeout ?? \"ignore\",\n\t\t\tidleTimeout: options.idleTimeout ?? 120,\n\t\t\tsendPingsAutomatically: options.sendPingsAutomatically ?? true,\n\t\t};\n\n\t\tconst lifecycle: ILifecycleServer<TEvents, SD, UpgradeCallback> = {\n\t\t\tonUpgrade: (callback) => {\n\t\t\t\tthis._onLifecycle(LifecycleTypes.upgrade, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\toffUpgrade: (callback) => {\n\t\t\t\tthis._offLifecycle(LifecycleTypes.upgrade, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\tonceUpgrade: (callback) => {\n\t\t\t\tthis._onceLifecycle(LifecycleTypes.upgrade, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\n\t\t\tonOpen: (callback) => {\n\t\t\t\tthis._onLifecycle(LifecycleTypes.open, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\toffOpen: (callback) => {\n\t\t\t\tthis._offLifecycle(LifecycleTypes.open, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\tonceOpen: (callback) => {\n\t\t\t\tthis._onceLifecycle(LifecycleTypes.open, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\n\t\t\tonAuthSuccess: (callback) => {\n\t\t\t\tthis._onLifecycle(LifecycleTypes.auth_success, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\toffAuthSuccess: (callback) => {\n\t\t\t\tthis._offLifecycle(LifecycleTypes.auth_success, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\tonceAuthSuccess: (callback) => {\n\t\t\t\tthis._onceLifecycle(LifecycleTypes.auth_success, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\n\t\t\tonAuthError: (callback) => {\n\t\t\t\tthis._onLifecycle(LifecycleTypes.auth_error, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\toffAuthError: (callback) => {\n\t\t\t\tthis._offLifecycle(LifecycleTypes.auth_error, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\tonceAuthError: (callback) => {\n\t\t\t\tthis._onceLifecycle(LifecycleTypes.auth_error, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\n\t\t\tonMessage: (callback) => {\n\t\t\t\tthis._onLifecycle(LifecycleTypes.message, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\toffMessage: (callback) => {\n\t\t\t\tthis._offLifecycle(LifecycleTypes.message, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\tonceMessage: (callback) => {\n\t\t\t\tthis._onceLifecycle(LifecycleTypes.message, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\n\t\t\tonClose: (callback) => {\n\t\t\t\tthis._onLifecycle(LifecycleTypes.close, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\toffClose: (callback) => {\n\t\t\t\tthis._offLifecycle(LifecycleTypes.close, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\tonceClose: (callback) => {\n\t\t\t\tthis._onceLifecycle(LifecycleTypes.close, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\n\t\t\tonError: (callback) => {\n\t\t\t\tthis._onLifecycle(LifecycleTypes.error, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\toffError: (callback) => {\n\t\t\t\tthis._offLifecycle(LifecycleTypes.error, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\tonceError: (callback) => {\n\t\t\t\tthis._onceLifecycle(LifecycleTypes.error, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t};\n\n\t\tthis.lifecycle = lifecycle;\n\n\t\tconst roomsLifecycle: IRoomsLifecycleServer<TEvents, SD> = {\n\t\t\tonJoin: (callback) => {\n\t\t\t\tthis._onLifecycle(LifecycleTypes.join_room, callback);\n\t\t\t\treturn roomsLifecycle;\n\t\t\t},\n\t\t\toffJoin: (callback) => {\n\t\t\t\tthis._offLifecycle(LifecycleTypes.join_room, callback);\n\t\t\t\treturn roomsLifecycle;\n\t\t\t},\n\t\t\tonceJoin: (callback) => {\n\t\t\t\tthis._onceLifecycle(LifecycleTypes.join_room, callback);\n\t\t\t\treturn roomsLifecycle;\n\t\t\t},\n\n\t\t\tonLeave: (callback) => {\n\t\t\t\tthis._onLifecycle(LifecycleTypes.leave_room, callback);\n\t\t\t\treturn roomsLifecycle;\n\t\t\t},\n\t\t\toffLeave: (callback) => {\n\t\t\t\tthis._offLifecycle(LifecycleTypes.leave_room, callback);\n\t\t\t\treturn roomsLifecycle;\n\t\t\t},\n\t\t\tonceLeave: (callback) => {\n\t\t\t\tthis._onceLifecycle(LifecycleTypes.leave_room, callback);\n\t\t\t\treturn roomsLifecycle;\n\t\t\t},\n\t\t};\n\n\t\tconst roomsBulkLifecycle: IRoomsBulkLifecycleServer<TEvents, SD> = {\n\t\t\tonJoin: (callback) => {\n\t\t\t\tthis._onLifecycle(LifecycleTypes.join_rooms, callback);\n\t\t\t\treturn roomsBulkLifecycle;\n\t\t\t},\n\t\t\toffJoin: (callback) => {\n\t\t\t\tthis._offLifecycle(LifecycleTypes.join_rooms, callback);\n\t\t\t\treturn roomsBulkLifecycle;\n\t\t\t},\n\t\t\tonceJoin: (callback) => {\n\t\t\t\tthis._onceLifecycle(LifecycleTypes.join_rooms, callback);\n\t\t\t\treturn roomsBulkLifecycle;\n\t\t\t},\n\n\t\t\tonLeave: (callback) => {\n\t\t\t\tthis._onLifecycle(LifecycleTypes.leave_rooms, callback);\n\t\t\t\treturn roomsBulkLifecycle;\n\t\t\t},\n\t\t\toffLeave: (callback) => {\n\t\t\t\tthis._offLifecycle(LifecycleTypes.leave_rooms, callback);\n\t\t\t\treturn roomsBulkLifecycle;\n\t\t\t},\n\t\t\tonceLeave: (callback) => {\n\t\t\t\tthis._onceLifecycle(LifecycleTypes.leave_rooms, callback);\n\t\t\t\treturn roomsBulkLifecycle;\n\t\t\t},\n\t\t};\n\n\t\tthis.rooms = {\n\t\t\tpublishRaw: this.publishRaw.bind(this),\n\t\t\temit: this.#publish.bind(this),\n\t\t\ton: this.#onRoom.bind(this),\n\t\t\toff: this.#offRoom.bind(this),\n\t\t\tonce: this.#onceRoom.bind(this),\n\t\t\tlifecycle: roomsLifecycle,\n\t\t\tbulk: {\n\t\t\t\temit: this.#publishMany.bind(this),\n\t\t\t\tlifecycle: roomsBulkLifecycle,\n\t\t\t},\n\t\t};\n\t}\n\n\tabstract attach(server: unknown, path: string): this;\n\tabstract destroy(): void;\n\n\tprotected abstract publishRaw(room: string, message: ServerOutgoingData, isBinary?: boolean, compress?: boolean): typeof this.rooms;\n\n\tprotected _destroy(): void {\n\t\tthis.#destroyed = true;\n\n\t\tfor (const socket of this.sockets.values()) {\n\t\t\tif (!socket.isClosed) {\n\t\t\t\tsocket.close(1001, \"server destroy\");\n\t\t\t}\n\t\t}\n\t\tthis.sockets.clear();\n\n\t\tthis._clearCallbacks();\n\t\tthis.#middlewares = [];\n\t}\n\n\temit<E extends StringNumberKeys<TEvents[\"emit\"]>, D extends NonNullable<TEvents[\"emit\"]>[E]>(event: E, data: D): this {\n\t\tif (this.#destroyed) {\n\t\t\treturn this;\n\t\t}\n\t\tconst message = this.encode({ event, data });\n\t\tthis.publishRaw(this.options.broadcastRoom, message);\n\t\treturn this;\n\t}\n\n\t#publish<\n\t\tR extends StringKeys<TEvents[\"emitRoom\"]>,\n\t\tE extends StringNumberKeys<NonNullable<TEvents[\"emitRoom\"]>[R]>,\n\t\tD extends NonNullable<TEvents[\"emitRoom\"]>[R][E],\n\t>(room: R, event: E, data: D): typeof this.rooms {\n\t\tif (this.#destroyed) {\n\t\t\treturn this.rooms;\n\t\t}\n\t\tconst message = this.encode({ room, event, data });\n\t\tthis.publishRaw(room, message);\n\t\treturn this.rooms;\n\t}\n\n\t#publishMany<\n\t\tRs extends NonNullable<TEvents[\"emitRooms\"]>[\"rooms\"],\n\t\tE extends StringNumberKeys<EventsForRooms<NonNullable<TEvents[\"emitRooms\"]>, Rs>>,\n\t\tD extends NonNullable<EventsForRooms<NonNullable<TEvents[\"emitRooms\"]>, Rs>>[E],\n\t>(rooms: Rs, event: E, data: D): typeof this.rooms.bulk {\n\t\tif (this.#destroyed) {\n\t\t\treturn this.rooms.bulk;\n\t\t}\n\t\tconst message = this.encode({ rooms, event, data });\n\t\tfor (const room of rooms) {\n\t\t\tthis.publishRaw(room, message);\n\t\t}\n\t\treturn this.rooms.bulk;\n\t}\n\n\ton<E extends StringNumberKeys<TEvents[\"listen\"]>, D extends NonNullable<TEvents[\"listen\"]>[E]>(\n\t\tevent: E,\n\t\tcallback: EventCallback<TEvents, SD, D>,\n\t): this {\n\t\tthis._on(event, callback);\n\t\treturn this;\n\t}\n\n\toff<E extends StringNumberKeys<TEvents[\"listen\"]>, D extends NonNullable<TEvents[\"listen\"]>[E]>(\n\t\tevent: E,\n\t\tcallback?: EventCallback<TEvents, SD, D>,\n\t): this {\n\t\tthis._off(event, callback);\n\t\treturn this;\n\t}\n\n\tonce<E extends StringNumberKeys<TEvents[\"listen\"]>, D extends NonNullable<TEvents[\"listen\"]>[E]>(\n\t\tevent: E,\n\t\tcallback: EventCallback<TEvents, SD, D>,\n\t): this {\n\t\tthis._once(event, callback);\n\t\treturn this;\n\t}\n\n\t#onRoom<\n\t\tR extends StringKeys<TEvents[\"listenRoom\"]>,\n\t\tE extends StringNumberKeys<NonNullable<TEvents[\"listenRoom\"]>[R]>,\n\t\tD extends NonNullable<TEvents[\"listenRoom\"]>[R][E],\n\t>(room: R, event: E, callback: RoomEventMiddleware<TEvents, SD, D>): typeof this.rooms {\n\t\tthis._onRoom(room, event, callback);\n\t\treturn this.rooms;\n\t}\n\n\t#offRoom<\n\t\tR extends StringKeys<TEvents[\"listenRoom\"]>,\n\t\tE extends StringNumberKeys<NonNullable<TEvents[\"listenRoom\"]>[R]>,\n\t\tD extends NonNullable<TEvents[\"listenRoom\"]>[R][E],\n\t>(room: R, event?: E, callback?: RoomEventMiddleware<TEvents, SD, D>): typeof this.rooms {\n\t\tthis._offRoom(room, event, callback);\n\t\treturn this.rooms;\n\t}\n\n\t#onceRoom<\n\t\tR extends StringKeys<TEvents[\"listenRoom\"]>,\n\t\tE extends StringNumberKeys<NonNullable<TEvents[\"listenRoom\"]>[R]>,\n\t\tD extends NonNullable<TEvents[\"listenRoom\"]>[R][E],\n\t>(room: R, event: E, callback: RoomEventMiddleware<TEvents, SD, D>): typeof this.rooms {\n\t\tthis._onceRoom(room, event, callback);\n\t\treturn this.rooms;\n\t}\n\n\tuse(fn: Middleware<TEvents, SD>): this {\n\t\tthis.#middlewares.push(fn);\n\t\treturn this;\n\t}\n\n\t#runMiddlewares<R extends string, E extends string | number, D>(\n\t\tsocket: ISocket<TEvents, SD>,\n\t\tctx: UserMessage<R, E, D>,\n\t\tfinalCallback: () => void,\n\t): void {\n\t\tlet index = 0;\n\t\tlet aborted = false;\n\n\t\tconst stack = Array.from(this.#middlewares);\n\n\t\tconst next: MiddlewareNext = (error) => {\n\t\t\tif (aborted) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (error) {\n\t\t\t\taborted = true;\n\t\t\t\tconst isTimeout = error instanceof Error && error.name === \"TimeoutError\";\n\t\t\t\tconst phase = isTimeout ? \"middlewareTimeout\" : \"middleware\";\n\t\t\t\tthis._triggerCallbacks(this._lifecycleCallbacksMap.get(LifecycleTypes.error), socket, { phase, error });\n\n\t\t\t\tconst option = isTimeout ? this.options.onMiddlewareTimeout : this.options.onMiddlewareError;\n\t\t\t\tif (option === \"close\") {\n\t\t\t\t\tsocket.close(1011, error instanceof Error ? error.message : String(error));\n\t\t\t\t} else if (typeof option === \"function\") {\n\t\t\t\t\toption(error, socket);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (index >= stack.length) {\n\t\t\t\ttry {\n\t\t\t\t\treturn finalCallback();\n\t\t\t\t} catch (err) {\n\t\t\t\t\tthis._triggerCallbacks(this._lifecycleCallbacksMap.get(LifecycleTypes.error), socket, { phase: \"finalCallback\", error: err });\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst middleware = stack[index++];\n\t\t\tlet called = false;\n\t\t\tlet timeoutId: ReturnType<typeof setTimeout> | null = null;\n\n\t\t\tconst execution = new Promise<void>((resolve, reject) => {\n\t\t\t\ttry {\n\t\t\t\t\tconst result = middleware(socket, ctx, (err) => {\n\t\t\t\t\t\tif (called) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcalled = true;\n\t\t\t\t\t\tif (err) {\n\t\t\t\t\t\t\treject(err);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tresolve();\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\n\t\t\t\t\tif (result instanceof Promise) {\n\t\t\t\t\t\tresult.then(\n\t\t\t\t\t\t\t() => {\n\t\t\t\t\t\t\t\tif (!called) {\n\t\t\t\t\t\t\t\t\tcalled = true;\n\t\t\t\t\t\t\t\t\tresolve();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t(err) => {\n\t\t\t\t\t\t\t\tif (!called) {\n\t\t\t\t\t\t\t\t\tcalled = true;\n\t\t\t\t\t\t\t\t\treject(err);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t} catch (syncErr) {\n\t\t\t\t\tif (!called) {\n\t\t\t\t\t\tcalled = true;\n\t\t\t\t\t\treject(syncErr);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tconst timeout = new Promise<void>((_, reject) => {\n\t\t\t\ttimeoutId = setTimeout(() => {\n\t\t\t\t\tif (!called) {\n\t\t\t\t\t\tcalled = true;\n\t\t\t\t\t\tconst timeoutError = new Error(`Middleware timeout after ${this.options.middlewareTimeout}ms`);\n\t\t\t\t\t\ttimeoutError.name = \"TimeoutError\";\n\t\t\t\t\t\treject(timeoutError);\n\t\t\t\t\t}\n\t\t\t\t}, this.options.middlewareTimeout);\n\t\t\t});\n\n\t\t\tPromise.race([execution, timeout])\n\t\t\t\t.then(() => next())\n\t\t\t\t.catch((err) => next(err))\n\t\t\t\t.finally(() => {\n\t\t\t\t\tif (timeoutId) {\n\t\t\t\t\t\tclearTimeout(timeoutId);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t};\n\n\t\tnext();\n\t}\n\n\tget destroyed(): boolean {\n\t\treturn this.#destroyed;\n\t}\n\n\t#rawMessageDescription(message: ServerIncomingData, isBinary: boolean): string {\n\t\tif (Array.isArray(message)) {\n\t\t\tconst total = message.reduce((s, b) => s + b.length, 0);\n\t\t\treturn `fragmented (${message.length} parts, ${total} bytes)`;\n\t\t}\n\t\tif (isBinary) {\n\t\t\tconst len = Buffer.isBuffer(message) ? message.length : message.byteLength;\n\t\t\treturn `binary (${len} bytes)`;\n\t\t}\n\t\treturn typeof message === \"string\" ? message : new TextDecoder().decode(message);\n\t}\n\n\tprotected message(socket: ISocket<TEvents, SD>, message: ServerIncomingData, isBinary: boolean) {\n\t\tthis._runSyncHooks(this._lifecycleCallbacksMap.get(LifecycleTypes.message), [socket, message, isBinary], (error) => {\n\t\t\tif (error != null) {\n\t\t\t\tthis._triggerCallbacks(this._lifecycleCallbacksMap.get(LifecycleTypes.error), socket, { phase: \"onMessage\", error });\n\t\t\t}\n\t\t});\n\n\t\tif (isBinary && (message.byteLength === 0 || (message instanceof Buffer && message.length === 0))) {\n\t\t\tsocket.sendRaw(new Uint8Array(0), true);\n\t\t\treturn;\n\t\t}\n\n\t\tlet parsed;\n\t\ttry {\n\t\t\tparsed = this.decode(message, isBinary);\n\t\t} catch (error) {\n\t\t\tconst raw = this.#rawMessageDescription(message, isBinary);\n\t\t\tthis._triggerCallbacks(this._lifecycleCallbacksMap.get(LifecycleTypes.error), socket, { phase: \"decode\", raw, error });\n\t\t\tsocket.close(1008, \"decode error\");\n\t\t\treturn;\n\t\t}\n\n\t\tif (parsed == null || typeof parsed !== \"object\") {\n\t\t\tconst error = new Error(\"Message must be an object\");\n\t\t\tthis._triggerCallbacks(this._lifecycleCallbacksMap.get(LifecycleTypes.error), socket, {\n\t\t\t\tphase: \"validation\",\n\t\t\t\traw: JSON.stringify(parsed),\n\t\t\t\terror,\n\t\t\t});\n\t\t\tsocket.close(1008, \"bad format\");\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.#handleAuthMessage(socket, parsed)) {\n\t\t\treturn;\n\t\t}\n\t\tif (!socket.isAuthenticated) {\n\t\t\treturn;\n\t\t}\n\t\tif (this.#handleJoinRoomMessage(socket, parsed)) {\n\t\t\treturn;\n\t\t}\n\t\tif (this.#handleLeaveRoomMessage(socket, parsed)) {\n\t\t\treturn;\n\t\t}\n\t\tif (this.#handleJoinRoomsMessage(socket, parsed)) {\n\t\t\treturn;\n\t\t}\n\t\tif (this.#handleLeaveRoomsMessage(socket, parsed)) {\n\t\t\treturn;\n\t\t}\n\t\tthis.#runMiddlewares(socket, parsed as UserMessage, () => {\n\t\t\tif (this.#handleRoomsEventMessage(socket, parsed)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (this.#handleRoomEventMessage(socket, parsed)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (this.#handleEventMessage(socket, parsed)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t});\n\t}\n\n\tprotected close(socket: ISocket<TEvents, SD>, code: number, reason: Buffer | ArrayBuffer) {\n\t\tif (this._debug && code === 4008) {\n\t\t\tconsole.warn(`Auth timeout for socket ${socket.id}`);\n\t\t}\n\t\tthis.sockets.delete(socket.id);\n\t\tsocket.close(code, Buffer.from(reason as ArrayBuffer).toString(\"utf8\"));\n\t\tthis._runSyncHooks(this._lifecycleCallbacksMap.get(LifecycleTypes.close), [socket, code, reason], (error) => {\n\t\t\tif (error != null) {\n\t\t\t\tthis._triggerCallbacks(this._lifecycleCallbacksMap.get(LifecycleTypes.error), socket, { phase: \"onClose\", error });\n\t\t\t}\n\t\t});\n\t}\n\n\t#handleAuthMessage<T extends object>(socket: ISocket<TEvents, SD>, parsed: T): boolean {\n\t\tif (!this._isLifecyclePayloadMessage(LifecycleTypes.auth, parsed)) {\n\t\t\treturn false;\n\t\t}\n\t\tsocket._handleAuth(parsed, this.options.auth, this.options.authTimeout, (err) => {\n\t\t\tif (err == null) {\n\t\t\t\tthis._runSyncHooks(this._lifecycleCallbacksMap.get(LifecycleTypes.auth_success), [socket], (error) => {\n\t\t\t\t\tif (error != null) {\n\t\t\t\t\t\tthis._triggerCallbacks(this._lifecycleCallbacksMap.get(LifecycleTypes.error), socket, { phase: \"onAuthSuccess\", error });\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tthis._runSyncHooks(this._lifecycleCallbacksMap.get(LifecycleTypes.open), [socket], (error) => {\n\t\t\t\t\tif (error != null) {\n\t\t\t\t\t\tthis._triggerCallbacks(this._lifecycleCallbacksMap.get(LifecycleTypes.error), socket, { phase: \"onOpen\", error });\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tconst ctx: ErrorContext = {\n\t\t\t\t\tphase: \"auth\",\n\t\t\t\t\terror: err instanceof Error ? err : new Error(String(err)),\n\t\t\t\t\tcode: 4003,\n\t\t\t\t};\n\t\t\t\tthis._runSyncHooks(this._lifecycleCallbacksMap.get(LifecycleTypes.auth_error), [socket, ctx], (error) => {\n\t\t\t\t\tif (error != null) {\n\t\t\t\t\t\tthis._triggerCallbacks(this._lifecycleCallbacksMap.get(LifecycleTypes.error), socket, { phase: \"onAuthError\", error });\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\t\treturn true;\n\t}\n\n\t#handleJoinRoomMessage<T extends object>(socket: ISocket<TEvents, SD>, parsed: T): boolean {\n\t\tif (!this._isLifecycleRoomMessage(LifecycleTypes.join_room, parsed)) {\n\t\t\treturn false;\n\t\t}\n\t\tthis.#runAsyncHooksOrNext(this._lifecycleCallbacksMap.get(LifecycleTypes.join_room), [socket, parsed.room], (error) => {\n\t\t\tif (error == null) {\n\t\t\t\tsocket.rooms.join(parsed.room);\n\t\t\t\tsocket.send({ type: LifecycleTypes.join_room_success, room: parsed.room });\n\t\t\t} else {\n\t\t\t\tsocket.send({ type: LifecycleTypes.join_room_error, room: parsed.room, data: { phase: \"onJoinRoom\", error } });\n\t\t\t}\n\t\t});\n\t\treturn true;\n\t}\n\n\t#handleLeaveRoomMessage<T extends object>(socket: ISocket<TEvents, SD>, parsed: T): boolean {\n\t\tif (!this._isLifecycleRoomMessage(LifecycleTypes.leave_room, parsed)) {\n\t\t\treturn false;\n\t\t}\n\t\tthis.#runAsyncHooksOrNext(this._lifecycleCallbacksMap.get(LifecycleTypes.leave_room), [socket, parsed.room], (error) => {\n\t\t\tif (error == null) {\n\t\t\t\tsocket.rooms.leave(parsed.room);\n\t\t\t\tsocket.send({ type: LifecycleTypes.leave_room_success, room: parsed.room });\n\t\t\t} else {\n\t\t\t\tsocket.send({ type: LifecycleTypes.leave_room_error, room: parsed.room, data: { phase: \"onLeaveRoom\", error } });\n\t\t\t}\n\t\t});\n\t\treturn true;\n\t}\n\n\t#handleJoinRoomsMessage<T extends object>(socket: ISocket<TEvents, SD>, parsed: T): boolean {\n\t\tif (!this._isLifecycleRoomsMessage(LifecycleTypes.join_rooms, parsed)) {\n\t\t\treturn false;\n\t\t}\n\t\tthis.#runAsyncHooksOrNext(this._lifecycleCallbacksMap.get(LifecycleTypes.join_rooms), [socket, parsed.rooms], (error) => {\n\t\t\tif (error == null) {\n\t\t\t\tsocket.rooms.bulk.join(parsed.rooms);\n\t\t\t\tsocket.send({ type: LifecycleTypes.join_rooms_success, rooms: parsed.rooms });\n\t\t\t} else {\n\t\t\t\tsocket.send({ type: LifecycleTypes.join_rooms_error, rooms: parsed.rooms, data: { phase: \"onJoinRooms\", error } });\n\t\t\t}\n\t\t});\n\t\treturn true;\n\t}\n\n\t#handleLeaveRoomsMessage<T extends object>(socket: ISocket<TEvents, SD>, parsed: T): boolean {\n\t\tif (!this._isLifecycleRoomsMessage(LifecycleTypes.leave_rooms, parsed)) {\n\t\t\treturn false;\n\t\t}\n\t\tthis.#runAsyncHooksOrNext(this._lifecycleCallbacksMap.get(LifecycleTypes.leave_rooms), [socket, parsed.rooms], (error) => {\n\t\t\tif (error == null) {\n\t\t\t\tsocket.rooms.bulk.leave(parsed.rooms);\n\t\t\t\tsocket.send({ type: LifecycleTypes.leave_rooms_success, rooms: parsed.rooms });\n\t\t\t} else {\n\t\t\t\tsocket.send({ type: LifecycleTypes.leave_rooms_error, rooms: parsed.rooms, data: { phase: \"onLeaveRooms\", error } });\n\t\t\t}\n\t\t});\n\t\treturn true;\n\t}\n\n\t#handleRoomsEventMessage<T extends object>(socket: ISocket<TEvents, SD>, parsed: T): boolean {\n\t\tif (!this._isRoomsEventMessage(parsed)) {\n\t\t\treturn false;\n\t\t}\n\t\tconst message = this.encode({ rooms: parsed.rooms, event: parsed.event, data: parsed.data });\n\t\tfor (const room of parsed.rooms) {\n\t\t\tthis.#runAsyncHooksOrNext(this._roomCallbacksMap.get(room)?.get(parsed.event), [socket, parsed.data], (error) => {\n\t\t\t\tif (error == null) {\n\t\t\t\t\tsocket.rooms.publishRaw(room, message);\n\t\t\t\t} else {\n\t\t\t\t\tthis._triggerCallbacks(this._lifecycleCallbacksMap.get(LifecycleTypes.error), socket, {\n\t\t\t\t\t\tphase: \"rooms message\",\n\t\t\t\t\t\traw: JSON.stringify(parsed),\n\t\t\t\t\t\terror,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\treturn true;\n\t}\n\n\t#handleRoomEventMessage<T extends object>(socket: ISocket<TEvents, SD>, parsed: T): boolean {\n\t\tif (!this._isRoomEventMessage(parsed)) {\n\t\t\treturn false;\n\t\t}\n\t\tthis.#runAsyncHooksOrNext(this._roomCallbacksMap.get(parsed.room)?.get(parsed.event), [socket, parsed.data], (error) => {\n\t\t\tif (error == null) {\n\t\t\t\tconst message = this.encode({ room: parsed.room, event: parsed.event, data: parsed.data });\n\t\t\t\tsocket.rooms.publishRaw(parsed.room, message);\n\t\t\t} else {\n\t\t\t\tthis._triggerCallbacks(this._lifecycleCallbacksMap.get(LifecycleTypes.error), socket, {\n\t\t\t\t\tphase: \"room message\",\n\t\t\t\t\traw: JSON.stringify(parsed),\n\t\t\t\t\terror,\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\t\treturn true;\n\t}\n\n\t#handleEventMessage<T extends object>(socket: ISocket<TEvents, SD>, parsed: T): boolean {\n\t\tif (!this._isEventMessage(parsed)) {\n\t\t\treturn false;\n\t\t}\n\t\tthis._triggerCallbacks(this._callbacksMap.get(parsed.event), socket, parsed.data);\n\t\treturn true;\n\t}\n\n\tprotected _runSyncHooks<Args extends Array<unknown>>(callbackSet: Set<AnyCallback> | undefined, args: Args, next: MiddlewareNext): void {\n\t\tif (!callbackSet) {\n\t\t\treturn next();\n\t\t}\n\t\tlet firstError: unknown = null;\n\t\tfor (const callback of callbackSet) {\n\t\t\ttry {\n\t\t\t\tcallback(...args);\n\t\t\t} catch (err) {\n\t\t\t\tif (this._debug) {\n\t\t\t\t\tconsole.error(err);\n\t\t\t\t}\n\t\t\t\tfirstError = firstError ?? err;\n\t\t\t}\n\t\t}\n\t\tnext(firstError);\n\t}\n\n\t#runAsyncHooksOrNext<Args extends Array<unknown>>(callbacks: Set<AnyCallback> | undefined, args: Args, finalCallback: MiddlewareNext): void {\n\t\tif (!callbacks || callbacks.size === 0) {\n\t\t\ttry {\n\t\t\t\tfinalCallback();\n\t\t\t} catch (err) {\n\t\t\t\tconst socket = args[0] instanceof SocketServerBase ? args[0] : undefined;\n\t\t\t\tthis._triggerCallbacks(this._lifecycleCallbacksMap.get(LifecycleTypes.error), socket, { phase: \"asyncHookFinal\", error: err });\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tconst stack = Array.from(callbacks);\n\t\tlet index = 0;\n\n\t\tconst next: MiddlewareNext = (error) => {\n\t\t\tif (error) {\n\t\t\t\treturn finalCallback(error);\n\t\t\t}\n\t\t\tif (index >= stack.length) {\n\t\t\t\ttry {\n\t\t\t\t\treturn finalCallback();\n\t\t\t\t} catch (err) {\n\t\t\t\t\tconst socket = args[0] instanceof SocketServerBase ? args[0] : undefined;\n\t\t\t\t\tthis._triggerCallbacks(this._lifecycleCallbacksMap.get(LifecycleTypes.error), socket, { phase: \"asyncHookFinal\", error: err });\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst callback = stack[index++];\n\t\t\tlet called = false;\n\t\t\tlet timeoutId: ReturnType<typeof setTimeout> | null = null;\n\n\t\t\tconst execution = new Promise<void>((resolve, reject) => {\n\t\t\t\ttry {\n\t\t\t\t\tconst result = callback(...args, (err?: unknown) => {\n\t\t\t\t\t\tif (called) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcalled = true;\n\t\t\t\t\t\tif (err) {\n\t\t\t\t\t\t\treject(err);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tresolve();\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\n\t\t\t\t\tif (result instanceof Promise) {\n\t\t\t\t\t\tresult.then(\n\t\t\t\t\t\t\t() => {\n\t\t\t\t\t\t\t\tif (!called) {\n\t\t\t\t\t\t\t\t\tcalled = true;\n\t\t\t\t\t\t\t\t\tresolve();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t(err) => {\n\t\t\t\t\t\t\t\tif (!called) {\n\t\t\t\t\t\t\t\t\tcalled = true;\n\t\t\t\t\t\t\t\t\treject(err);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t} catch (syncErr) {\n\t\t\t\t\tif (!called) {\n\t\t\t\t\t\tcalled = true;\n\t\t\t\t\t\treject(syncErr);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tconst timeout = new Promise<void>((_, reject) => {\n\t\t\t\ttimeoutId = setTimeout(() => {\n\t\t\t\t\tif (!called) {\n\t\t\t\t\t\tcalled = true;\n\t\t\t\t\t\tconst timeoutError = new Error(`Room middleware timeout after ${this.options.roomMiddlewareTimeout}ms`);\n\t\t\t\t\t\ttimeoutError.name = \"TimeoutError\";\n\t\t\t\t\t\treject(timeoutError);\n\t\t\t\t\t}\n\t\t\t\t}, this.options.roomMiddlewareTimeout);\n\t\t\t});\n\n\t\t\tPromise.race([execution, timeout])\n\t\t\t\t.then(() => next())\n\t\t\t\t.catch((err) => next(err))\n\t\t\t\t.finally(() => {\n\t\t\t\t\tif (timeoutId) {\n\t\t\t\t\t\tclearTimeout(timeoutId);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t};\n\n\t\tnext();\n\t}\n}\n"],"mappings":"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"}
{"version":3,"file":"index.js","names":["#authState","#closed","#encode","#publish","#publishMany","#joinRooms","#leaveRooms","#clearAuthTimer","#authTimer","#setAuthFailed","#setAuthSuccess","#handleNoAuth","#sendUnchecked","#publish","#onRoom","#offRoom","#onceRoom","#publishMany","#destroyed","#middlewares","#isPromiseLike","#rawMessageDescription","#handleAuthMessage","#handleJoinRoomMessage","#handleLeaveRoomMessage","#handleJoinRoomsMessage","#handleLeaveRoomsMessage","#runMiddlewares","#handleRoomsEventMessage","#handleRoomEventMessage","#handleEventMessage","#runAsyncHooksOrNext"],"sources":["../src/socket-server-base.ts","../src/byte-socket-server-base.ts"],"sourcesContent":["// packages/server/src/socket-server-base.ts\nimport {\n\tAuthState,\n\tLifecycleTypes,\n\ttype ErrorContext,\n\ttype EventsForRooms,\n\ttype LifecycleMessage,\n\ttype SocketEvents,\n\ttype StringKeys,\n\ttype StringNumberKeys,\n\ttype UserMessage,\n} from \"@bytesocket/core\";\nimport type { ISocket, ISocketRooms } from \"./interfaces\";\nimport type { AuthFunction, MiddlewareNext, ServerOutgoingData, SocketData } from \"./types\";\n\nexport abstract class SocketServerBase<TEvents extends SocketEvents = SocketEvents, SD extends SocketData = SocketData> implements ISocket<\n\tTEvents,\n\tSD\n> {\n\treadonly rooms: ISocketRooms<TEvents>;\n\n\tpayload: any = {};\n\tlocals: any = {};\n\n\t#encode: <R extends string, E extends string | number, D>(\n\t\tpayload: LifecycleMessage<R, D> | UserMessage<R, E, D>,\n\t) => string | Buffer<ArrayBufferLike>;\n\t#authState: AuthState = AuthState.idle;\n\t#authTimer: ReturnType<typeof setTimeout> | null = null;\n\t#closed: boolean = false;\n\n\tget isAuthenticated(): boolean {\n\t\treturn this.#authState === AuthState.none || this.#authState === AuthState.success;\n\t}\n\tget isClosed(): boolean {\n\t\treturn this.#closed;\n\t}\n\tget canSend(): boolean {\n\t\treturn !this.#closed && this.isAuthenticated;\n\t}\n\n\tabstract readonly userData: SD;\n\tget id(): string {\n\t\treturn this.userData.socketKey;\n\t}\n\tget url(): string {\n\t\treturn this.userData.url;\n\t}\n\tget query(): string {\n\t\treturn this.userData.query;\n\t}\n\tget cookie(): string {\n\t\treturn this.userData.cookie;\n\t}\n\tget authorization(): string {\n\t\treturn this.userData.authorization;\n\t}\n\tget userAgent(): string {\n\t\treturn this.userData.userAgent;\n\t}\n\tget host(): string {\n\t\treturn this.userData.host;\n\t}\n\tget xForwardedFor(): string {\n\t\treturn this.userData.xForwardedFor;\n\t}\n\n\tprotected abstract readonly broadcastRoom: string;\n\n\tconstructor(\n\t\tencode: <R extends string, E extends string | number, D>(\n\t\t\tpayload: LifecycleMessage<R, D> | UserMessage<R, E, D>,\n\t\t) => string | Buffer<ArrayBufferLike>,\n\t) {\n\t\tthis.#encode = encode;\n\t\tthis.rooms = {\n\t\t\tpublishRaw: this.publishRaw.bind(this),\n\t\t\temit: this.#publish.bind(this),\n\t\t\tjoin: this.joinRoom.bind(this),\n\t\t\tleave: this.leaveRoom.bind(this),\n\t\t\tlist: this.getRoomList.bind(this),\n\t\t\tbulk: {\n\t\t\t\temit: this.#publishMany.bind(this),\n\t\t\t\tjoin: this.#joinRooms.bind(this),\n\t\t\t\tleave: this.#leaveRooms.bind(this),\n\t\t\t},\n\t\t};\n\t}\n\n\tabstract sendRaw(message: ServerOutgoingData, isBinary?: boolean, compress?: boolean): this;\n\n\tprotected abstract getRoomList(includeBroadcast?: boolean): string[];\n\n\tprotected abstract publishRaw(room: string, message: ServerOutgoingData, isBinary?: boolean, compress?: boolean): typeof this.rooms;\n\n\tprotected abstract joinRoom(room: string): typeof this.rooms;\n\n\tprotected abstract leaveRoom(room: string): typeof this.rooms;\n\n\tabstract close(code?: number, reason?: string): void;\n\n\tprotected startHeartbeat(): void {}\n\n\tprotected clearHeartbeat(): void {}\n\n\temit<E extends StringNumberKeys<TEvents[\"emit\"]>, D extends NonNullable<TEvents[\"emit\"]>[E]>(event: E, data: D): this {\n\t\tthis.send({ event, data });\n\t\treturn this;\n\t}\n\n\tsend<R extends string, E extends string | number, D>(payload: LifecycleMessage<R, D> | UserMessage<R, E, D>): this {\n\t\tif (!this.canSend) {\n\t\t\treturn this;\n\t\t}\n\t\tconst message = this.#encode(payload);\n\t\tthis.sendRaw(message);\n\t\treturn this;\n\t}\n\n\tbroadcast<E extends StringNumberKeys<TEvents[\"emit\"]>, D extends NonNullable<TEvents[\"emit\"]>[E]>(event: E, data: D): this {\n\t\tif (!this.canSend) {\n\t\t\treturn this;\n\t\t}\n\t\tconst message = this.#encode({ event, data });\n\t\tthis.publishRaw(this.broadcastRoom, message);\n\t\treturn this;\n\t}\n\n\t#sendUnchecked<R extends string, E extends string | number, D>(payload: LifecycleMessage<R, D> | UserMessage<R, E, D>): void {\n\t\tif (this.#closed) {\n\t\t\treturn;\n\t\t}\n\t\tconst message = this.#encode(payload);\n\t\tthis.sendRaw(message);\n\t}\n\n\t#publish<\n\t\tR extends StringKeys<TEvents[\"emitRoom\"]>,\n\t\tE extends StringNumberKeys<NonNullable<TEvents[\"emitRoom\"]>[R]>,\n\t\tD extends NonNullable<TEvents[\"emitRoom\"]>[R][E],\n\t>(room: R, event: E, data: D): typeof this.rooms {\n\t\tif (!this.canSend) {\n\t\t\treturn this.rooms;\n\t\t}\n\t\tconst message = this.#encode({ room, event, data });\n\t\tthis.publishRaw(room, message);\n\t\treturn this.rooms;\n\t}\n\n\t#publishMany<\n\t\tRs extends NonNullable<TEvents[\"emitRooms\"]>[\"rooms\"],\n\t\tE extends StringNumberKeys<EventsForRooms<NonNullable<TEvents[\"emitRooms\"]>, Rs>>,\n\t\tD extends NonNullable<EventsForRooms<NonNullable<TEvents[\"emitRooms\"]>, Rs>>[E],\n\t>(rooms: Rs, event: E, data: D): typeof this.rooms.bulk {\n\t\tif (!this.canSend) {\n\t\t\treturn this.rooms.bulk;\n\t\t}\n\t\tconst message = this.#encode({ rooms, event, data });\n\t\tfor (const room of rooms) {\n\t\t\tthis.publishRaw(room, message);\n\t\t}\n\t\treturn this.rooms.bulk;\n\t}\n\n\t#joinRooms(rooms: string[]): typeof this.rooms.bulk {\n\t\tif (!this.canSend) {\n\t\t\treturn this.rooms.bulk;\n\t\t}\n\t\tfor (const room of rooms) {\n\t\t\tthis.joinRoom(room);\n\t\t}\n\t\treturn this.rooms.bulk;\n\t}\n\n\t#leaveRooms(rooms: string[]): typeof this.rooms.bulk {\n\t\tif (!this.canSend) {\n\t\t\treturn this.rooms.bulk;\n\t\t}\n\t\tfor (const room of rooms) {\n\t\t\tthis.leaveRoom(room);\n\t\t}\n\t\treturn this.rooms.bulk;\n\t}\n\n\tprotected _close(): void {\n\t\tthis.#closed = true;\n\t\tthis.#clearAuthTimer();\n\t\tthis.clearHeartbeat();\n\t}\n\n\t_handleAuth<D>(\n\t\tparsed: { type: LifecycleTypes.auth; data: D } | null,\n\t\tauth: AuthFunction<TEvents, SD, D> | undefined,\n\t\tauthTimeout: number,\n\t\tnext: MiddlewareNext,\n\t) {\n\t\tif (auth && parsed !== null) {\n\t\t\tif (this.#authState !== AuthState.idle) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.#authState = AuthState.pending;\n\t\t\tif (authTimeout > 0) {\n\t\t\t\tthis.#authTimer = setTimeout(() => {\n\t\t\t\t\tif (!this.isClosed && !this.isAuthenticated) {\n\t\t\t\t\t\tconst err = new Error(\"Auth timeout\");\n\t\t\t\t\t\tthis.#setAuthFailed({ phase: \"auth\", error: err, code: 4008 });\n\t\t\t\t\t\tnext(err);\n\t\t\t\t\t}\n\t\t\t\t}, authTimeout);\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tauth(this, parsed.data, (payload, error) => {\n\t\t\t\t\tif (error) {\n\t\t\t\t\t\tconst err = error || new Error(\"Auth failed\");\n\t\t\t\t\t\tthis.#setAuthFailed({ phase: \"auth\", error: err, code: 4003 });\n\t\t\t\t\t\tnext(err);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tthis.#setAuthSuccess(payload);\n\t\t\t\t\tthis.rooms.join(this.broadcastRoom);\n\t\t\t\t\tthis.startHeartbeat();\n\t\t\t\t\tnext();\n\t\t\t\t});\n\t\t\t} catch (err) {\n\t\t\t\tthis.#setAuthFailed({ phase: \"auth\", error: err, code: 4003 });\n\t\t\t\tnext(err);\n\t\t\t}\n\t\t} else {\n\t\t\tthis.#handleNoAuth();\n\t\t\tthis.startHeartbeat();\n\t\t\tnext();\n\t\t}\n\t}\n\n\t#handleNoAuth() {\n\t\tif (this.#closed || this.#authState !== AuthState.idle) {\n\t\t\treturn;\n\t\t}\n\t\tthis.#authState = AuthState.none;\n\t\tthis.rooms.join(this.broadcastRoom);\n\t}\n\n\t#setAuthSuccess<P>(payload: P): void {\n\t\tif (this.#closed || this.#authState !== AuthState.pending) {\n\t\t\treturn;\n\t\t}\n\t\tthis.#clearAuthTimer();\n\t\tthis.#authState = AuthState.success;\n\t\tthis.payload = payload;\n\t\tthis.#sendUnchecked({ type: LifecycleTypes.auth_success });\n\t}\n\n\t#setAuthFailed(ctx: ErrorContext): void {\n\t\tif (this.#closed || this.#authState !== AuthState.pending) {\n\t\t\treturn;\n\t\t}\n\t\tthis.#clearAuthTimer();\n\t\tthis.#authState = AuthState.failed;\n\t\tthis.#sendUnchecked({ type: LifecycleTypes.auth_error, data: ctx });\n\t\tthis.close(ctx.code, ctx.phase);\n\t}\n\n\t#clearAuthTimer(): void {\n\t\tif (this.#authTimer) {\n\t\t\tclearTimeout(this.#authTimer);\n\t\t\tthis.#authTimer = null;\n\t\t}\n\t}\n}\n","// packages/server/src/byte-socket-server-base.ts\nimport {\n\tByteSocketBase,\n\tLifecycleTypes,\n\ttype AnyCallback,\n\ttype ErrorContext,\n\ttype EventsForRooms,\n\ttype SocketEvents,\n\ttype StringKeys,\n\ttype StringNumberKeys,\n\ttype UserMessage,\n} from \"@bytesocket/core\";\nimport type { IByteSocket, ILifecycleServer, IRoomsBulkLifecycleServer, IRoomsLifecycleServer, IRoomsServer, ISocket } from \"./interfaces\";\nimport { SocketServerBase } from \"./socket-server-base\";\nimport type {\n\tByteSocketOptionsBase,\n\tEventCallback,\n\tMiddleware,\n\tMiddlewareNext,\n\tRoomEventMiddleware,\n\tServerIncomingData,\n\tServerOutgoingData,\n\tSocketData,\n} from \"./types\";\n\ntype RequiredOptions =\n\t| \"middlewareTimeout\"\n\t| \"roomMiddlewareTimeout\"\n\t| \"authTimeout\"\n\t| \"broadcastRoom\"\n\t| \"onMiddlewareError\"\n\t| \"onMiddlewareTimeout\"\n\t| \"idleTimeout\"\n\t| \"sendPingsAutomatically\";\n\nexport abstract class ByteSocketServerBase<\n\tTEvents extends SocketEvents = SocketEvents,\n\tSD extends SocketData = SocketData,\n\tUpgradeCallback extends AnyCallback = AnyCallback,\n>\n\textends ByteSocketBase\n\timplements IByteSocket<TEvents, SD, UpgradeCallback>\n{\n\t// ──── Namespaces ────────────────────────────────────────────────────────────────────────\n\treadonly lifecycle: ILifecycleServer<TEvents, SD, UpgradeCallback>;\n\treadonly rooms: IRoomsServer<TEvents, SD>;\n\treadonly sockets = new Map<string, ISocket<TEvents, SD>>();\n\n\t// ──── States ────────────────────────────────────────────────────────────────────────\n\n\tprotected options: Omit<ByteSocketOptionsBase<TEvents, SD>, RequiredOptions | \"debug\" | \"serialization\" | \"msgpackrOptions\"> &\n\t\tPick<Required<ByteSocketOptionsBase<TEvents, SD>>, RequiredOptions>;\n\t#middlewares: Middleware<TEvents, SD>[] = [];\n\t#destroyed = false;\n\n\tconstructor(options: ByteSocketOptionsBase<TEvents, SD> = {}) {\n\t\tsuper(options);\n\n\t\tthis.options = {\n\t\t\t...options,\n\t\t\tmiddlewareTimeout: options.middlewareTimeout ?? 0,\n\t\t\troomMiddlewareTimeout: options.roomMiddlewareTimeout ?? 0,\n\t\t\tauthTimeout: options.authTimeout ?? 0,\n\t\t\tbroadcastRoom: options.broadcastRoom ?? \"__bytesocket_broadcast__\",\n\t\t\tonMiddlewareError: options.onMiddlewareError ?? \"ignore\",\n\t\t\tonMiddlewareTimeout: options.onMiddlewareTimeout ?? \"ignore\",\n\t\t\tidleTimeout: options.idleTimeout ?? 120000,\n\t\t\tsendPingsAutomatically: options.sendPingsAutomatically ?? true,\n\t\t};\n\n\t\tconst lifecycle: ILifecycleServer<TEvents, SD, UpgradeCallback> = {\n\t\t\tonUpgrade: (callback) => {\n\t\t\t\tthis._onLifecycle(LifecycleTypes.upgrade, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\toffUpgrade: (callback) => {\n\t\t\t\tthis._offLifecycle(LifecycleTypes.upgrade, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\tonceUpgrade: (callback) => {\n\t\t\t\tthis._onceLifecycle(LifecycleTypes.upgrade, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\n\t\t\tonOpen: (callback) => {\n\t\t\t\tthis._onLifecycle(LifecycleTypes.open, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\toffOpen: (callback) => {\n\t\t\t\tthis._offLifecycle(LifecycleTypes.open, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\tonceOpen: (callback) => {\n\t\t\t\tthis._onceLifecycle(LifecycleTypes.open, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\n\t\t\tonAuthSuccess: (callback) => {\n\t\t\t\tthis._onLifecycle(LifecycleTypes.auth_success, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\toffAuthSuccess: (callback) => {\n\t\t\t\tthis._offLifecycle(LifecycleTypes.auth_success, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\tonceAuthSuccess: (callback) => {\n\t\t\t\tthis._onceLifecycle(LifecycleTypes.auth_success, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\n\t\t\tonAuthError: (callback) => {\n\t\t\t\tthis._onLifecycle(LifecycleTypes.auth_error, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\toffAuthError: (callback) => {\n\t\t\t\tthis._offLifecycle(LifecycleTypes.auth_error, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\tonceAuthError: (callback) => {\n\t\t\t\tthis._onceLifecycle(LifecycleTypes.auth_error, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\n\t\t\tonMessage: (callback) => {\n\t\t\t\tthis._onLifecycle(LifecycleTypes.message, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\toffMessage: (callback) => {\n\t\t\t\tthis._offLifecycle(LifecycleTypes.message, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\tonceMessage: (callback) => {\n\t\t\t\tthis._onceLifecycle(LifecycleTypes.message, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\n\t\t\tonClose: (callback) => {\n\t\t\t\tthis._onLifecycle(LifecycleTypes.close, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\toffClose: (callback) => {\n\t\t\t\tthis._offLifecycle(LifecycleTypes.close, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\tonceClose: (callback) => {\n\t\t\t\tthis._onceLifecycle(LifecycleTypes.close, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\n\t\t\tonError: (callback) => {\n\t\t\t\tthis._onLifecycle(LifecycleTypes.error, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\toffError: (callback) => {\n\t\t\t\tthis._offLifecycle(LifecycleTypes.error, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t\tonceError: (callback) => {\n\t\t\t\tthis._onceLifecycle(LifecycleTypes.error, callback);\n\t\t\t\treturn lifecycle;\n\t\t\t},\n\t\t};\n\n\t\tthis.lifecycle = lifecycle;\n\n\t\tconst roomsLifecycle: IRoomsLifecycleServer<TEvents, SD> = {\n\t\t\tonJoin: (callback) => {\n\t\t\t\tthis._onLifecycle(LifecycleTypes.join_room, callback);\n\t\t\t\treturn roomsLifecycle;\n\t\t\t},\n\t\t\toffJoin: (callback) => {\n\t\t\t\tthis._offLifecycle(LifecycleTypes.join_room, callback);\n\t\t\t\treturn roomsLifecycle;\n\t\t\t},\n\t\t\tonceJoin: (callback) => {\n\t\t\t\tthis._onceLifecycle(LifecycleTypes.join_room, callback);\n\t\t\t\treturn roomsLifecycle;\n\t\t\t},\n\n\t\t\tonLeave: (callback) => {\n\t\t\t\tthis._onLifecycle(LifecycleTypes.leave_room, callback);\n\t\t\t\treturn roomsLifecycle;\n\t\t\t},\n\t\t\toffLeave: (callback) => {\n\t\t\t\tthis._offLifecycle(LifecycleTypes.leave_room, callback);\n\t\t\t\treturn roomsLifecycle;\n\t\t\t},\n\t\t\tonceLeave: (callback) => {\n\t\t\t\tthis._onceLifecycle(LifecycleTypes.leave_room, callback);\n\t\t\t\treturn roomsLifecycle;\n\t\t\t},\n\t\t};\n\n\t\tconst roomsBulkLifecycle: IRoomsBulkLifecycleServer<TEvents, SD> = {\n\t\t\tonJoin: (callback) => {\n\t\t\t\tthis._onLifecycle(LifecycleTypes.join_rooms, callback);\n\t\t\t\treturn roomsBulkLifecycle;\n\t\t\t},\n\t\t\toffJoin: (callback) => {\n\t\t\t\tthis._offLifecycle(LifecycleTypes.join_rooms, callback);\n\t\t\t\treturn roomsBulkLifecycle;\n\t\t\t},\n\t\t\tonceJoin: (callback) => {\n\t\t\t\tthis._onceLifecycle(LifecycleTypes.join_rooms, callback);\n\t\t\t\treturn roomsBulkLifecycle;\n\t\t\t},\n\n\t\t\tonLeave: (callback) => {\n\t\t\t\tthis._onLifecycle(LifecycleTypes.leave_rooms, callback);\n\t\t\t\treturn roomsBulkLifecycle;\n\t\t\t},\n\t\t\toffLeave: (callback) => {\n\t\t\t\tthis._offLifecycle(LifecycleTypes.leave_rooms, callback);\n\t\t\t\treturn roomsBulkLifecycle;\n\t\t\t},\n\t\t\tonceLeave: (callback) => {\n\t\t\t\tthis._onceLifecycle(LifecycleTypes.leave_rooms, callback);\n\t\t\t\treturn roomsBulkLifecycle;\n\t\t\t},\n\t\t};\n\n\t\tthis.rooms = {\n\t\t\tpublishRaw: this.publishRaw.bind(this),\n\t\t\temit: this.#publish.bind(this),\n\t\t\ton: this.#onRoom.bind(this),\n\t\t\toff: this.#offRoom.bind(this),\n\t\t\tonce: this.#onceRoom.bind(this),\n\t\t\tlifecycle: roomsLifecycle,\n\t\t\tbulk: {\n\t\t\t\temit: this.#publishMany.bind(this),\n\t\t\t\tlifecycle: roomsBulkLifecycle,\n\t\t\t},\n\t\t};\n\t}\n\n\tabstract attach(server: unknown, path: string): this;\n\tabstract destroy(): void;\n\n\tprotected abstract publishRaw(room: string, message: ServerOutgoingData, isBinary?: boolean, compress?: boolean): typeof this.rooms;\n\n\tprotected _destroy(): void {\n\t\tthis.#destroyed = true;\n\n\t\tfor (const socket of this.sockets.values()) {\n\t\t\tif (!socket.isClosed) {\n\t\t\t\tsocket.close(1001, \"server destroy\");\n\t\t\t}\n\t\t}\n\t\tthis.sockets.clear();\n\n\t\tthis._clearCallbacks();\n\t\tthis.#middlewares = [];\n\t}\n\n\temit<E extends StringNumberKeys<TEvents[\"emit\"]>, D extends NonNullable<TEvents[\"emit\"]>[E]>(event: E, data: D): this {\n\t\tif (this.#destroyed) {\n\t\t\treturn this;\n\t\t}\n\t\tconst message = this.encode({ event, data });\n\t\tthis.publishRaw(this.options.broadcastRoom, message);\n\t\treturn this;\n\t}\n\n\t#publish<\n\t\tR extends StringKeys<TEvents[\"emitRoom\"]>,\n\t\tE extends StringNumberKeys<NonNullable<TEvents[\"emitRoom\"]>[R]>,\n\t\tD extends NonNullable<TEvents[\"emitRoom\"]>[R][E],\n\t>(room: R, event: E, data: D): typeof this.rooms {\n\t\tif (this.#destroyed) {\n\t\t\treturn this.rooms;\n\t\t}\n\t\tconst message = this.encode({ room, event, data });\n\t\tthis.publishRaw(room, message);\n\t\treturn this.rooms;\n\t}\n\n\t#publishMany<\n\t\tRs extends NonNullable<TEvents[\"emitRooms\"]>[\"rooms\"],\n\t\tE extends StringNumberKeys<EventsForRooms<NonNullable<TEvents[\"emitRooms\"]>, Rs>>,\n\t\tD extends NonNullable<EventsForRooms<NonNullable<TEvents[\"emitRooms\"]>, Rs>>[E],\n\t>(rooms: Rs, event: E, data: D): typeof this.rooms.bulk {\n\t\tif (this.#destroyed) {\n\t\t\treturn this.rooms.bulk;\n\t\t}\n\t\tconst message = this.encode({ rooms, event, data });\n\t\tfor (const room of rooms) {\n\t\t\tthis.publishRaw(room, message);\n\t\t}\n\t\treturn this.rooms.bulk;\n\t}\n\n\ton<E extends StringNumberKeys<TEvents[\"listen\"]>, D extends NonNullable<TEvents[\"listen\"]>[E]>(\n\t\tevent: E,\n\t\tcallback: EventCallback<TEvents, SD, D>,\n\t): this {\n\t\tthis._on(event, callback);\n\t\treturn this;\n\t}\n\n\toff<E extends StringNumberKeys<TEvents[\"listen\"]>, D extends NonNullable<TEvents[\"listen\"]>[E]>(\n\t\tevent: E,\n\t\tcallback?: EventCallback<TEvents, SD, D>,\n\t): this {\n\t\tthis._off(event, callback);\n\t\treturn this;\n\t}\n\n\tonce<E extends StringNumberKeys<TEvents[\"listen\"]>, D extends NonNullable<TEvents[\"listen\"]>[E]>(\n\t\tevent: E,\n\t\tcallback: EventCallback<TEvents, SD, D>,\n\t): this {\n\t\tthis._once(event, callback);\n\t\treturn this;\n\t}\n\n\t#onRoom<\n\t\tR extends StringKeys<TEvents[\"listenRoom\"]>,\n\t\tE extends StringNumberKeys<NonNullable<TEvents[\"listenRoom\"]>[R]>,\n\t\tD extends NonNullable<TEvents[\"listenRoom\"]>[R][E],\n\t>(room: R, event: E, callback: RoomEventMiddleware<TEvents, SD, D>): typeof this.rooms {\n\t\tthis._onRoom(room, event, callback);\n\t\treturn this.rooms;\n\t}\n\n\t#offRoom<\n\t\tR extends StringKeys<TEvents[\"listenRoom\"]>,\n\t\tE extends StringNumberKeys<NonNullable<TEvents[\"listenRoom\"]>[R]>,\n\t\tD extends NonNullable<TEvents[\"listenRoom\"]>[R][E],\n\t>(room: R, event?: E, callback?: RoomEventMiddleware<TEvents, SD, D>): typeof this.rooms {\n\t\tthis._offRoom(room, event, callback);\n\t\treturn this.rooms;\n\t}\n\n\t#onceRoom<\n\t\tR extends StringKeys<TEvents[\"listenRoom\"]>,\n\t\tE extends StringNumberKeys<NonNullable<TEvents[\"listenRoom\"]>[R]>,\n\t\tD extends NonNullable<TEvents[\"listenRoom\"]>[R][E],\n\t>(room: R, event: E, callback: RoomEventMiddleware<TEvents, SD, D>): typeof this.rooms {\n\t\tthis._onceRoom(room, event, callback);\n\t\treturn this.rooms;\n\t}\n\n\tuse(fn: Middleware<TEvents, SD>): this {\n\t\tthis.#middlewares.push(fn);\n\t\treturn this;\n\t}\n\n\t#isPromiseLike(value: unknown): value is PromiseLike<unknown> {\n\t\treturn !!value && typeof (value as PromiseLike<unknown>).then === \"function\";\n\t}\n\n\t#runMiddlewares<R extends string, E extends string | number, D>(\n\t\tsocket: ISocket<TEvents, SD>,\n\t\tctx: UserMessage<R, E, D>,\n\t\tfinalCallback: () => void,\n\t): void {\n\t\tlet index = 0;\n\t\tlet aborted = false;\n\n\t\tconst stack = Array.from(this.#middlewares);\n\n\t\tconst next: MiddlewareNext = (error) => {\n\t\t\tif (aborted) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (error) {\n\t\t\t\taborted = true;\n\t\t\t\tconst isTimeout = error instanceof Error && error.name === \"TimeoutError\";\n\t\t\t\tconst phase = isTimeout ? \"middlewareTimeout\" : \"middleware\";\n\t\t\t\tthis._triggerCallbacks(this._lifecycleCallbacksMap.get(LifecycleTypes.error), socket, { phase, error });\n\n\t\t\t\tconst option = isTimeout ? this.options.onMiddlewareTimeout : this.options.onMiddlewareError;\n\t\t\t\tif (option === \"close\") {\n\t\t\t\t\tsocket.close(1011, error instanceof Error ? error.message : String(error));\n\t\t\t\t} else if (typeof option === \"function\") {\n\t\t\t\t\toption(error, socket);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (index >= stack.length) {\n\t\t\t\ttry {\n\t\t\t\t\treturn finalCallback();\n\t\t\t\t} catch (err) {\n\t\t\t\t\tthis._triggerCallbacks(this._lifecycleCallbacksMap.get(LifecycleTypes.error), socket, { phase: \"finalCallback\", error: err });\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst middleware = stack[index++];\n\t\t\tlet called = false;\n\t\t\tlet timeoutId: ReturnType<typeof setTimeout> | null = null;\n\n\t\t\tconst execution = new Promise<void>((resolve, reject) => {\n\t\t\t\ttry {\n\t\t\t\t\tconst result = middleware(socket, ctx, (err) => {\n\t\t\t\t\t\tif (called) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcalled = true;\n\t\t\t\t\t\tif (err) {\n\t\t\t\t\t\t\treject(err);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tresolve();\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\n\t\t\t\t\tif (this.#isPromiseLike(result)) {\n\t\t\t\t\t\tresult.then(\n\t\t\t\t\t\t\t() => {\n\t\t\t\t\t\t\t\tif (!called) {\n\t\t\t\t\t\t\t\t\tcalled = true;\n\t\t\t\t\t\t\t\t\tresolve();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t(err) => {\n\t\t\t\t\t\t\t\tif (!called) {\n\t\t\t\t\t\t\t\t\tcalled = true;\n\t\t\t\t\t\t\t\t\treject(err);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t} catch (syncErr) {\n\t\t\t\t\tif (!called) {\n\t\t\t\t\t\tcalled = true;\n\t\t\t\t\t\treject(syncErr);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tconst tasks: Promise<void>[] = [execution];\n\n\t\t\tif (this.options.middlewareTimeout > 0) {\n\t\t\t\tconst timeout = new Promise<void>((_, reject) => {\n\t\t\t\t\ttimeoutId = setTimeout(() => {\n\t\t\t\t\t\tif (!called) {\n\t\t\t\t\t\t\tcalled = true;\n\t\t\t\t\t\t\tconst timeoutError = new Error(`Middleware timeout after ${this.options.middlewareTimeout}ms`);\n\t\t\t\t\t\t\ttimeoutError.name = \"TimeoutError\";\n\t\t\t\t\t\t\treject(timeoutError);\n\t\t\t\t\t\t}\n\t\t\t\t\t}, this.options.middlewareTimeout);\n\t\t\t\t});\n\t\t\t\ttasks.push(timeout);\n\t\t\t}\n\n\t\t\tPromise.race(tasks)\n\t\t\t\t.then(() => next())\n\t\t\t\t.catch((err) => next(err))\n\t\t\t\t.finally(() => {\n\t\t\t\t\tif (timeoutId) {\n\t\t\t\t\t\tclearTimeout(timeoutId);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t};\n\n\t\tnext();\n\t}\n\n\tget destroyed(): boolean {\n\t\treturn this.#destroyed;\n\t}\n\n\t#rawMessageDescription(message: ServerIncomingData, isBinary: boolean): string {\n\t\tif (Array.isArray(message)) {\n\t\t\tconst total = message.reduce((s, b) => s + b.length, 0);\n\t\t\treturn `fragmented (${message.length} parts, ${total} bytes)`;\n\t\t}\n\t\tif (isBinary) {\n\t\t\tconst len = Buffer.isBuffer(message) ? message.length : message.byteLength;\n\t\t\treturn `binary (${len} bytes)`;\n\t\t}\n\t\treturn typeof message === \"string\" ? message : new TextDecoder().decode(message);\n\t}\n\n\tprotected message(socket: ISocket<TEvents, SD>, message: ServerIncomingData, isBinary: boolean) {\n\t\tthis._runSyncHooks(this._lifecycleCallbacksMap.get(LifecycleTypes.message), [socket, message, isBinary], (error) => {\n\t\t\tif (error != null) {\n\t\t\t\tthis._triggerCallbacks(this._lifecycleCallbacksMap.get(LifecycleTypes.error), socket, { phase: \"onMessage\", error });\n\t\t\t}\n\t\t});\n\n\t\tif (isBinary && (message.byteLength === 0 || (message instanceof Buffer && message.length === 0))) {\n\t\t\tsocket.sendRaw(new Uint8Array(0), true);\n\t\t\treturn;\n\t\t}\n\n\t\tlet parsed;\n\t\ttry {\n\t\t\tparsed = this.decode(message, isBinary);\n\t\t} catch (error) {\n\t\t\tconst raw = this.#rawMessageDescription(message, isBinary);\n\t\t\tthis._triggerCallbacks(this._lifecycleCallbacksMap.get(LifecycleTypes.error), socket, { phase: \"decode\", raw, error });\n\t\t\tsocket.close(1008, \"decode error\");\n\t\t\treturn;\n\t\t}\n\n\t\tif (parsed == null || typeof parsed !== \"object\") {\n\t\t\tconst error = new Error(\"Message must be an object\");\n\t\t\tthis._triggerCallbacks(this._lifecycleCallbacksMap.get(LifecycleTypes.error), socket, {\n\t\t\t\tphase: \"validation\",\n\t\t\t\traw: JSON.stringify(parsed),\n\t\t\t\terror,\n\t\t\t});\n\t\t\tsocket.close(1008, \"bad format\");\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.#handleAuthMessage(socket, parsed)) {\n\t\t\treturn;\n\t\t}\n\t\tif (!socket.isAuthenticated) {\n\t\t\treturn;\n\t\t}\n\t\tif (this.#handleJoinRoomMessage(socket, parsed)) {\n\t\t\treturn;\n\t\t}\n\t\tif (this.#handleLeaveRoomMessage(socket, parsed)) {\n\t\t\treturn;\n\t\t}\n\t\tif (this.#handleJoinRoomsMessage(socket, parsed)) {\n\t\t\treturn;\n\t\t}\n\t\tif (this.#handleLeaveRoomsMessage(socket, parsed)) {\n\t\t\treturn;\n\t\t}\n\t\tthis.#runMiddlewares(socket, parsed as UserMessage, () => {\n\t\t\tif (this.#handleRoomsEventMessage(socket, parsed)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (this.#handleRoomEventMessage(socket, parsed)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (this.#handleEventMessage(socket, parsed)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t});\n\t}\n\n\tprotected close(socket: ISocket<TEvents, SD>, code: number, reason: Buffer | ArrayBuffer) {\n\t\tif (this._debug && code === 4008) {\n\t\t\tconsole.warn(`Auth timeout for socket ${socket.id}`);\n\t\t}\n\t\tthis.sockets.delete(socket.id);\n\t\tsocket.close(code, Buffer.from(reason as ArrayBuffer).toString(\"utf8\"));\n\t\tthis._runSyncHooks(this._lifecycleCallbacksMap.get(LifecycleTypes.close), [socket, code, reason], (error) => {\n\t\t\tif (error != null) {\n\t\t\t\tthis._triggerCallbacks(this._lifecycleCallbacksMap.get(LifecycleTypes.error), socket, { phase: \"onClose\", error });\n\t\t\t}\n\t\t});\n\t}\n\n\t#handleAuthMessage<T extends object>(socket: ISocket<TEvents, SD>, parsed: T): boolean {\n\t\tif (!this._isLifecyclePayloadMessage(LifecycleTypes.auth, parsed)) {\n\t\t\treturn false;\n\t\t}\n\t\tsocket._handleAuth(parsed, this.options.auth, this.options.authTimeout, (err) => {\n\t\t\tif (err == null) {\n\t\t\t\tthis._runSyncHooks(this._lifecycleCallbacksMap.get(LifecycleTypes.auth_success), [socket], (error) => {\n\t\t\t\t\tif (error != null) {\n\t\t\t\t\t\tthis._triggerCallbacks(this._lifecycleCallbacksMap.get(LifecycleTypes.error), socket, { phase: \"onAuthSuccess\", error });\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tthis._runSyncHooks(this._lifecycleCallbacksMap.get(LifecycleTypes.open), [socket], (error) => {\n\t\t\t\t\tif (error != null) {\n\t\t\t\t\t\tthis._triggerCallbacks(this._lifecycleCallbacksMap.get(LifecycleTypes.error), socket, { phase: \"onOpen\", error });\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tconst ctx: ErrorContext = {\n\t\t\t\t\tphase: \"auth\",\n\t\t\t\t\terror: err instanceof Error ? err : new Error(String(err)),\n\t\t\t\t\tcode: 4003,\n\t\t\t\t};\n\t\t\t\tthis._runSyncHooks(this._lifecycleCallbacksMap.get(LifecycleTypes.auth_error), [socket, ctx], (error) => {\n\t\t\t\t\tif (error != null) {\n\t\t\t\t\t\tthis._triggerCallbacks(this._lifecycleCallbacksMap.get(LifecycleTypes.error), socket, { phase: \"onAuthError\", error });\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\t\treturn true;\n\t}\n\n\t#handleJoinRoomMessage<T extends object>(socket: ISocket<TEvents, SD>, parsed: T): boolean {\n\t\tif (!this._isLifecycleRoomMessage(LifecycleTypes.join_room, parsed)) {\n\t\t\treturn false;\n\t\t}\n\t\tthis.#runAsyncHooksOrNext(this._lifecycleCallbacksMap.get(LifecycleTypes.join_room), [socket, parsed.room], (error) => {\n\t\t\tif (error == null) {\n\t\t\t\tsocket.rooms.join(parsed.room);\n\t\t\t\tsocket.send({ type: LifecycleTypes.join_room_success, room: parsed.room });\n\t\t\t} else {\n\t\t\t\tsocket.send({ type: LifecycleTypes.join_room_error, room: parsed.room, data: { phase: \"onJoinRoom\", error } });\n\t\t\t}\n\t\t});\n\t\treturn true;\n\t}\n\n\t#handleLeaveRoomMessage<T extends object>(socket: ISocket<TEvents, SD>, parsed: T): boolean {\n\t\tif (!this._isLifecycleRoomMessage(LifecycleTypes.leave_room, parsed)) {\n\t\t\treturn false;\n\t\t}\n\t\tthis.#runAsyncHooksOrNext(this._lifecycleCallbacksMap.get(LifecycleTypes.leave_room), [socket, parsed.room], (error) => {\n\t\t\tif (error == null) {\n\t\t\t\tsocket.rooms.leave(parsed.room);\n\t\t\t\tsocket.send({ type: LifecycleTypes.leave_room_success, room: parsed.room });\n\t\t\t} else {\n\t\t\t\tsocket.send({ type: LifecycleTypes.leave_room_error, room: parsed.room, data: { phase: \"onLeaveRoom\", error } });\n\t\t\t}\n\t\t});\n\t\treturn true;\n\t}\n\n\t#handleJoinRoomsMessage<T extends object>(socket: ISocket<TEvents, SD>, parsed: T): boolean {\n\t\tif (!this._isLifecycleRoomsMessage(LifecycleTypes.join_rooms, parsed)) {\n\t\t\treturn false;\n\t\t}\n\t\tthis.#runAsyncHooksOrNext(this._lifecycleCallbacksMap.get(LifecycleTypes.join_rooms), [socket, parsed.rooms], (error) => {\n\t\t\tif (error == null) {\n\t\t\t\tsocket.rooms.bulk.join(parsed.rooms);\n\t\t\t\tsocket.send({ type: LifecycleTypes.join_rooms_success, rooms: parsed.rooms });\n\t\t\t} else {\n\t\t\t\tsocket.send({ type: LifecycleTypes.join_rooms_error, rooms: parsed.rooms, data: { phase: \"onJoinRooms\", error } });\n\t\t\t}\n\t\t});\n\t\treturn true;\n\t}\n\n\t#handleLeaveRoomsMessage<T extends object>(socket: ISocket<TEvents, SD>, parsed: T): boolean {\n\t\tif (!this._isLifecycleRoomsMessage(LifecycleTypes.leave_rooms, parsed)) {\n\t\t\treturn false;\n\t\t}\n\t\tthis.#runAsyncHooksOrNext(this._lifecycleCallbacksMap.get(LifecycleTypes.leave_rooms), [socket, parsed.rooms], (error) => {\n\t\t\tif (error == null) {\n\t\t\t\tsocket.rooms.bulk.leave(parsed.rooms);\n\t\t\t\tsocket.send({ type: LifecycleTypes.leave_rooms_success, rooms: parsed.rooms });\n\t\t\t} else {\n\t\t\t\tsocket.send({ type: LifecycleTypes.leave_rooms_error, rooms: parsed.rooms, data: { phase: \"onLeaveRooms\", error } });\n\t\t\t}\n\t\t});\n\t\treturn true;\n\t}\n\n\t#handleRoomsEventMessage<T extends object>(socket: ISocket<TEvents, SD>, parsed: T): boolean {\n\t\tif (!this._isRoomsEventMessage(parsed)) {\n\t\t\treturn false;\n\t\t}\n\t\tconst message = this.encode({ rooms: parsed.rooms, event: parsed.event, data: parsed.data });\n\t\tfor (const room of parsed.rooms) {\n\t\t\tthis.#runAsyncHooksOrNext(this._roomCallbacksMap.get(room)?.get(parsed.event), [socket, parsed.data], (error) => {\n\t\t\t\tif (error == null) {\n\t\t\t\t\tsocket.rooms.publishRaw(room, message);\n\t\t\t\t} else {\n\t\t\t\t\tthis._triggerCallbacks(this._lifecycleCallbacksMap.get(LifecycleTypes.error), socket, {\n\t\t\t\t\t\tphase: \"rooms message\",\n\t\t\t\t\t\traw: JSON.stringify(parsed),\n\t\t\t\t\t\terror,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\treturn true;\n\t}\n\n\t#handleRoomEventMessage<T extends object>(socket: ISocket<TEvents, SD>, parsed: T): boolean {\n\t\tif (!this._isRoomEventMessage(parsed)) {\n\t\t\treturn false;\n\t\t}\n\t\tthis.#runAsyncHooksOrNext(this._roomCallbacksMap.get(parsed.room)?.get(parsed.event), [socket, parsed.data], (error) => {\n\t\t\tif (error == null) {\n\t\t\t\tconst message = this.encode({ room: parsed.room, event: parsed.event, data: parsed.data });\n\t\t\t\tsocket.rooms.publishRaw(parsed.room, message);\n\t\t\t} else {\n\t\t\t\tthis._triggerCallbacks(this._lifecycleCallbacksMap.get(LifecycleTypes.error), socket, {\n\t\t\t\t\tphase: \"room message\",\n\t\t\t\t\traw: JSON.stringify(parsed),\n\t\t\t\t\terror,\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\t\treturn true;\n\t}\n\n\t#handleEventMessage<T extends object>(socket: ISocket<TEvents, SD>, parsed: T): boolean {\n\t\tif (!this._isEventMessage(parsed)) {\n\t\t\treturn false;\n\t\t}\n\t\tthis._triggerCallbacks(this._callbacksMap.get(parsed.event), socket, parsed.data);\n\t\treturn true;\n\t}\n\n\tprotected _runSyncHooks<Args extends Array<unknown>>(callbackSet: Set<AnyCallback> | undefined, args: Args, next: MiddlewareNext): void {\n\t\tif (!callbackSet) {\n\t\t\treturn next();\n\t\t}\n\t\tlet firstError: unknown = null;\n\t\tfor (const callback of callbackSet) {\n\t\t\ttry {\n\t\t\t\tcallback(...args);\n\t\t\t} catch (err) {\n\t\t\t\tif (this._debug) {\n\t\t\t\t\tconsole.error(err);\n\t\t\t\t}\n\t\t\t\tfirstError = firstError ?? err;\n\t\t\t}\n\t\t}\n\t\tnext(firstError);\n\t}\n\n\t#runAsyncHooksOrNext<Args extends Array<unknown>>(callbacks: Set<AnyCallback> | undefined, args: Args, finalCallback: MiddlewareNext): void {\n\t\tif (!callbacks || callbacks.size === 0) {\n\t\t\ttry {\n\t\t\t\tfinalCallback();\n\t\t\t} catch (err) {\n\t\t\t\tconst socket = args[0] instanceof SocketServerBase ? args[0] : undefined;\n\t\t\t\tthis._triggerCallbacks(this._lifecycleCallbacksMap.get(LifecycleTypes.error), socket, { phase: \"asyncHookFinal\", error: err });\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tconst stack = Array.from(callbacks);\n\t\tlet index = 0;\n\n\t\tconst next: MiddlewareNext = (error) => {\n\t\t\tif (error) {\n\t\t\t\treturn finalCallback(error);\n\t\t\t}\n\t\t\tif (index >= stack.length) {\n\t\t\t\ttry {\n\t\t\t\t\treturn finalCallback();\n\t\t\t\t} catch (err) {\n\t\t\t\t\tconst socket = args[0] instanceof SocketServerBase ? args[0] : undefined;\n\t\t\t\t\tthis._triggerCallbacks(this._lifecycleCallbacksMap.get(LifecycleTypes.error), socket, { phase: \"asyncHookFinal\", error: err });\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst callback = stack[index++];\n\t\t\tlet called = false;\n\t\t\tlet timeoutId: ReturnType<typeof setTimeout> | null = null;\n\n\t\t\tconst execution = new Promise<void>((resolve, reject) => {\n\t\t\t\ttry {\n\t\t\t\t\tconst result = callback(...args, (err?: unknown) => {\n\t\t\t\t\t\tif (called) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcalled = true;\n\t\t\t\t\t\tif (err) {\n\t\t\t\t\t\t\treject(err);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tresolve();\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\n\t\t\t\t\tif (this.#isPromiseLike(result)) {\n\t\t\t\t\t\tresult.then(\n\t\t\t\t\t\t\t() => {\n\t\t\t\t\t\t\t\tif (!called) {\n\t\t\t\t\t\t\t\t\tcalled = true;\n\t\t\t\t\t\t\t\t\tresolve();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t(err) => {\n\t\t\t\t\t\t\t\tif (!called) {\n\t\t\t\t\t\t\t\t\tcalled = true;\n\t\t\t\t\t\t\t\t\treject(err);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t} catch (syncErr) {\n\t\t\t\t\tif (!called) {\n\t\t\t\t\t\tcalled = true;\n\t\t\t\t\t\treject(syncErr);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tconst tasks: Promise<void>[] = [execution];\n\n\t\t\tif (this.options.roomMiddlewareTimeout > 0) {\n\t\t\t\tconst timeout = new Promise<void>((_, reject) => {\n\t\t\t\t\ttimeoutId = setTimeout(() => {\n\t\t\t\t\t\tif (!called) {\n\t\t\t\t\t\t\tcalled = true;\n\t\t\t\t\t\t\tconst timeoutError = new Error(`Room middleware timeout after ${this.options.roomMiddlewareTimeout}ms`);\n\t\t\t\t\t\t\ttimeoutError.name = \"TimeoutError\";\n\t\t\t\t\t\t\treject(timeoutError);\n\t\t\t\t\t\t}\n\t\t\t\t\t}, this.options.roomMiddlewareTimeout);\n\t\t\t\t});\n\t\t\t\ttasks.push(timeout);\n\t\t\t}\n\n\t\t\tPromise.race(tasks)\n\t\t\t\t.then(() => next())\n\t\t\t\t.catch((err) => next(err))\n\t\t\t\t.finally(() => {\n\t\t\t\t\tif (timeoutId) {\n\t\t\t\t\t\tclearTimeout(timeoutId);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t};\n\n\t\tnext();\n\t}\n}\n"],"mappings":"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"}

@@ -1,2 +0,2 @@

import { p as ByteSocketOptionsBase, t as ByteSocketServerBase } from "../byte-socket-server-base-CLZDN4De.cjs";
import { p as ByteSocketOptionsBase, t as ByteSocketServerBase } from "../byte-socket-server-base-Cri0yUAN.cjs";
import { SocketEvents } from "@bytesocket/core";

@@ -79,3 +79,3 @@ import { ClientRequestArgs } from "node:http";

}>;
interface CreateByteSocketServerResponse<B extends ByteSocketServerBase = ByteSocketServerBase> {
type CreateByteSocketServerResponse<B extends ByteSocketServerBase = ByteSocketServerBase> = {
io: B;

@@ -85,3 +85,3 @@ server: unknown;

listenSocket?: unknown;
}
};
declare function createClient(port: number, url?: string, options?: WebSocket.ClientOptions | ClientRequestArgs): Promise<WebSocket>;

@@ -88,0 +88,0 @@ //#endregion

@@ -1,1 +0,1 @@

{"version":3,"file":"index.d.cts","names":[],"sources":["../../src/test-utils/auth.ts","../../src/test-utils/connection.ts","../../src/test-utils/heartbeat.ts","../../src/test-utils/lifecycle.ts","../../src/test-utils/messaging.ts","../../src/test-utils/rooms-bulk.ts","../../src/test-utils/rooms-single.ts","../../src/test-utils/index.ts"],"mappings":"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"}
{"version":3,"file":"index.d.cts","names":[],"sources":["../../src/test-utils/auth.ts","../../src/test-utils/connection.ts","../../src/test-utils/heartbeat.ts","../../src/test-utils/lifecycle.ts","../../src/test-utils/messaging.ts","../../src/test-utils/rooms-bulk.ts","../../src/test-utils/rooms-single.ts","../../src/test-utils/index.ts"],"mappings":"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"}

@@ -1,2 +0,2 @@

import { p as ByteSocketOptionsBase, t as ByteSocketServerBase } from "../byte-socket-server-base-DFXqLJh0.js";
import { p as ByteSocketOptionsBase, t as ByteSocketServerBase } from "../byte-socket-server-base-3oCYTtHD.js";
import { SocketEvents } from "@bytesocket/core";

@@ -79,3 +79,3 @@ import { ClientRequestArgs } from "node:http";

}>;
interface CreateByteSocketServerResponse<B extends ByteSocketServerBase = ByteSocketServerBase> {
type CreateByteSocketServerResponse<B extends ByteSocketServerBase = ByteSocketServerBase> = {
io: B;

@@ -85,3 +85,3 @@ server: unknown;

listenSocket?: unknown;
}
};
declare function createClient(port: number, url?: string, options?: WebSocket.ClientOptions | ClientRequestArgs): Promise<WebSocket>;

@@ -88,0 +88,0 @@ //#endregion

@@ -1,1 +0,1 @@

{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/test-utils/auth.ts","../../src/test-utils/connection.ts","../../src/test-utils/heartbeat.ts","../../src/test-utils/lifecycle.ts","../../src/test-utils/messaging.ts","../../src/test-utils/rooms-bulk.ts","../../src/test-utils/rooms-single.ts","../../src/test-utils/index.ts"],"mappings":";;;;;;;iBAQgB,cAAA,WAAyB,oBAAA,CAAqB,UAAA,IAAc,oBAAA,CAAqB,UAAA,EAAA,CAAA;EAC9F,EAAA;EAAI,SAAA;EAAW,UAAA;EAAY,EAAA;EAAI;AAAA,UAAiB,MAAA,EAClD,gBAAA,GAAmB,OAAA,GAAU,qBAAA,CAAsB,UAAA,MAAgB,CAAA,EACnE,sBAAA,QAA8B,OAAA,CAAQ,8BAAA,CAA+B,CAAA,IACrE,uBAAA,GAA0B,GAAA,EAAK,8BAAA,CAA+B,CAAA;;;iBCL/C,oBAAA,WAA+B,oBAAA,CAAqB,UAAA,IAAc,oBAAA,CAAqB,UAAA,EAAA,CAAA;EACpG,EAAA;EAAI,SAAA;EAAW,UAAA;EAAY,EAAA;EAAI;AAAA,UAAiB,MAAA,EAClD,gBAAA,GAAmB,OAAA,GAAU,qBAAA,CAAsB,UAAA,MAAgB,CAAA,EACnE,sBAAA,QAA8B,OAAA,CAAQ,8BAAA,CAA+B,CAAA,IACrE,uBAAA,GAA0B,GAAA,EAAK,8BAAA,CAA+B,CAAA;;;iBCL/C,mBAAA,WAA8B,oBAAA,CAAqB,UAAA,IAAc,oBAAA,CAAqB,UAAA,EAAA,CAAA;EACnG,EAAA;EAAI,SAAA;EAAW,UAAA;EAAY,EAAA;EAAI;AAAA,UAAiB,MAAA,EAClD,sBAAA,QAA8B,OAAA,CAAQ,8BAAA,CAA+B,CAAA,IACrE,uBAAA,GAA0B,GAAA,EAAK,8BAAA,CAA+B,CAAA,mBAAW,8BAAA,CAAA,CAAA;;;iBCH1D,mBAAA,WAA8B,oBAAA,CAAqB,UAAA,IAAc,oBAAA,CAAqB,UAAA,EAAA,CAAA;EACnG,EAAA;EAAI,SAAA;EAAW,UAAA;EAAY,EAAA;EAAI;AAAA,UAAiB,MAAA,EAClD,sBAAA,QAA8B,OAAA,CAAQ,8BAAA,CAA+B,CAAA,IACrE,uBAAA,GAA0B,GAAA,EAAK,8BAAA,CAA+B,CAAA;;;iBCF/C,mBAAA,WAA8B,oBAAA,CAAqB,UAAA,IAAc,oBAAA,CAAqB,UAAA,EAAA,CAAA;EACnG,EAAA;EAAI,SAAA;EAAW,UAAA;EAAY,EAAA;EAAI;AAAA,UAAiB,MAAA,EAClD,gBAAA,GAAmB,OAAA,GAAU,qBAAA,CAAsB,UAAA,MAAgB,CAAA,EACnE,sBAAA,QAA8B,OAAA,CAAQ,8BAAA,CAA+B,CAAA,IACrE,uBAAA,GAA0B,GAAA,EAAK,8BAAA,CAA+B,CAAA;;;iBCL/C,mBAAA,WAA8B,oBAAA,CAAqB,UAAA,IAAc,oBAAA,CAAqB,UAAA,EAAA,CAAA;EACnG,EAAA;EAAI,SAAA;EAAW,UAAA;EAAY,EAAA;EAAI;AAAA,UAAiB,MAAA,EAClD,sBAAA,QAA8B,OAAA,CAAQ,8BAAA,CAA+B,CAAA,IACrE,uBAAA,GAA0B,GAAA,EAAK,8BAAA,CAA+B,CAAA;;;iBCF/C,qBAAA,WAAgC,oBAAA,CAAqB,UAAA,IAAc,oBAAA,CAAqB,UAAA,EAAA,CAAA;EACrG,EAAA;EAAI,SAAA;EAAW,UAAA;EAAY,EAAA;EAAI;AAAA,UAAiB,MAAA,EAClD,gBAAA,GAAmB,OAAA,GAAU,qBAAA,CAAsB,UAAA,MAAgB,CAAA,EACnE,sBAAA,QAA8B,OAAA,CAAQ,8BAAA,CAA+B,CAAA,IACrE,uBAAA,GAA0B,GAAA,EAAK,8BAAA,CAA+B,CAAA;;;KCLnD,UAAA,GAAa,YAAA;EACxB,IAAA;IAAQ,OAAA;EAAA;EACR,SAAA;IAAa,IAAA;EAAA;AAAA;AAAA,UAEG,8BAAA,WAAyC,oBAAA,GAAuB,oBAAA;EAChF,EAAA,EAAI,CAAA;EACJ,MAAA;EACA,IAAA;EACA,YAAA;AAAA;AAAA,iBAGe,YAAA,CACf,IAAA,UACA,GAAA,WACA,OAAA,GAAU,SAAA,CAAU,aAAA,GAAgB,iBAAA,GAClC,OAAA,CAAQ,SAAA"}
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/test-utils/auth.ts","../../src/test-utils/connection.ts","../../src/test-utils/heartbeat.ts","../../src/test-utils/lifecycle.ts","../../src/test-utils/messaging.ts","../../src/test-utils/rooms-bulk.ts","../../src/test-utils/rooms-single.ts","../../src/test-utils/index.ts"],"mappings":"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"}
{
"name": "@bytesocket/server",
"version": "0.3.1",
"version": "0.4.0",
"description": "Shared server logic for ByteSocket WebSocket server implementations",

@@ -46,7 +46,7 @@ "keywords": [

"dependencies": {
"@bytesocket/core": "0.3.1"
"@bytesocket/core": "0.4.0"
},
"devDependencies": {
"@types/node": "^22.19.17",
"msgpackr": "^1.11.10"
"@types/node": "^22.4.0",
"msgpackr": "^2.0.1"
},

@@ -53,0 +53,0 @@ "engines": {

@@ -12,3 +12,3 @@ # @bytesocket/server

[![GitHub stars](https://img.shields.io/github/stars/a7med3ouda/bytesocket?style=flat&logo=github)](https://github.com/a7med3ouda/bytesocket)
[![Socket Badge](https://badge.socket.dev/npm/package/@bytesocket/server/0.3.1)](https://badge.socket.dev/npm/package/@bytesocket/server/0.3.1)
[![Socket Badge](https://badge.socket.dev/npm/package/@bytesocket/server)](https://socket.dev/npm/package/@bytesocket/server)

@@ -114,6 +114,6 @@ ## Features

| `broadcastRoom` | `string` | `"__bytesocket_broadcast__"` | Internal room used for global broadcasts |
| `authTimeout` | `number` | `5000` | Max milliseconds to wait for an auth response |
| `middlewareTimeout` | `number` | `5000` | Timeout for global middleware |
| `roomMiddlewareTimeout` | `number` | `5000` | Timeout for room middleware |
| `idleTimeout` | `number` | `120` | Seconds before an idle connection is closed |
| `authTimeout` | `number` | `0` | Max milliseconds to wait for an auth response |
| `middlewareTimeout` | `number` | `0` | Timeout for global middleware |
| `roomMiddlewareTimeout` | `number` | `0` | Timeout for room middleware |
| `idleTimeout` | `number` | `120000` | Milliseconds before an idle connection is closed |
| `sendPingsAutomatically` | `boolean` | `true` | Send WebSocket pings to keep the connection alive |

@@ -120,0 +120,0 @@ | `origins` | `string[]` | - | Allowed origin list (empty = all allowed) |

import { AnyCallback, ByteSocketBase, ErrorContext, EventsForRooms, IByteSocketBase, LifecycleMessage, LifecycleTypes, MsgpackrOptions, SocketEvents, StringKeys, StringNumberKeys, UserMessage } from "@bytesocket/core";
import { UUID } from "node:crypto";
//#region src/types.d.ts
/** The data types actually received from outside.*/
type ServerIncomingData = Buffer | ArrayBuffer | Uint8Array;
/** The data types actually accepted by the server `server.send()` or `ws.send()` methods.*/
type ServerOutgoingData = string | ServerIncomingData;
/**
* Callback used by the authentication function to return the authentication result.
* @param payload - The authenticated user data to attach to the socket.
* @param error - Optional error if authentication failed.
*/
type AuthCallback = (payload: any, error?: Error) => void;
/**
* Authentication function signature. Called when a client sends an auth message.
*
* @typeParam SD - The socket data type (must extend `SocketData`).
* @typeParam D - The type of the authentication data sent by the client.
*
* @example
* const auth: AuthFunction = (socket, data, callback) => {
* if (data.token === "secret") {
* callback({ userId: 1 });
* } else {
* callback(null, new Error("Invalid token"));
* }
* };
*/
type AuthFunction<TEvents extends SocketEvents, SD extends SocketData, D = any> = (socket: ISocket<TEvents, SD>, data: D, callback: AuthCallback) => void;
/**
* Callback for global event listeners.
*
* @typeParam SD - The socket data type.
* @typeParam D - The type of the event data.
*
* @example
* socket.on("userJoined", (socket, data) => {
* console.log(`User ${data.userId} joined`);
* });
*/
type EventCallback<TEvents extends SocketEvents, SD extends SocketData, D> = (socket: ISocket<TEvents, SD>, data: D) => void;
/**
* Middleware function for room-scoped events. Can inspect or block the broadcast.
*
* @typeParam SD - The socket data type.
* @typeParam D - The type of the event data.
*
* @example
* io.rooms.on("chat", "message", (socket, data, next) => {
* if (data.text.includes("badword")) {
* next(new Error("Profanity not allowed"));
* } else {
* next();
* }
* });
*
* // Also supports async functions / Promises
* io.rooms.on("chat", "message", async (socket, data, next) => {
* const isValid = await validateMessage(data);
* if (!isValid) {
* return next(new Error("Invalid"));
* }
* next();
* });
*/
type RoomEventMiddleware<TEvents extends SocketEvents, SD extends SocketData, D> = (socket: ISocket<TEvents, SD>, data: D, next: MiddlewareNext) => void | Promise<void>;
/** Next function for middleware chains. Call `next()` to proceed, or `next(error)` to abort. */
type MiddlewareNext = (error?: unknown | null) => void;
/**
* Global middleware function. Runs before any user message is processed.
*
* @typeParam SD - The socket data type.
*
* @example
* io.use((socket, ctx, next) => {
* console.log("Received:", ctx);
* next();
* });
*/
type Middleware<TEvents extends SocketEvents = SocketEvents, SD extends SocketData = SocketData> = (socket: ISocket<TEvents, SD>, ctx: UserMessage, next: MiddlewareNext) => void | Promise<void>;
/**
* Data automatically attached to every socket by the server.
* Contains HTTP request information available during the WebSocket upgrade.
*/
type SocketData = {
/** Unique identifier for the socket (UUID v4). */socketKey: UUID; /** The url string from the upgrade request. */
url: string; /** The query string from the upgrade request. */
query: string; /** The `Host` header value. */
host: string; /** The `Cookie` header value. */
cookie: string; /** The `User-Agent` header value. */
userAgent: string; /** The `Authorization` header value. */
authorization: string; /** The `X-Forwarded-For` header value. */
xForwardedFor: string;
};
/**
* Configuration options for the ByteSocket server.
*
* @typeParam TEvents - The socket events definition.
* @typeParam SD - The socket data type (must extend `SocketData`).
*
* @example
* const io = new ByteSocket({
* debug: true,
* authTimeout: 10000,
* origins: ["https://example.com"],
* serialization: "binary",
* auth: (socket, data, callback) => {
* // validate token
* callback({ userId: 1 });
* }
* });
*/
type ByteSocketOptionsBase<TEvents extends SocketEvents = SocketEvents, SD extends SocketData = SocketData> = {
/** Enable debug logging to console. @default false */debug?: boolean; /** Timeout in milliseconds for global middleware execution. @default 5000 */
middlewareTimeout?: number; /** Timeout in milliseconds for room event middleware execution. @default 5000 */
roomMiddlewareTimeout?: number; /** Timeout for authentication response in milliseconds. @default 5000 */
authTimeout?: number; /** List of allowed origins for CORS. If empty, all origins are allowed. */
origins?: string[]; /** Serialization format: `"json"` or `"binary"` (msgpack). @default "binary" */
serialization?: "json" | "binary"; /** Room name used for global broadcasts. @default "__bytesocket_broadcast__" */
broadcastRoom?: string; /** Options passed directly to the underlying msgpackr Packr instance. */
msgpackrOptions?: MsgpackrOptions; /** Action to take when a global middleware error occurs. @default "ignore" */
onMiddlewareError?: "ignore" | "close" | ((error: unknown, socket: ISocket<TEvents, SD>) => void); /** Action to take when a global middleware times out. @default "ignore" */
onMiddlewareTimeout?: "ignore" | "close" | ((error: unknown, socket: ISocket<TEvents, SD>) => void); /** Authentication configuration. */
auth?: AuthFunction<TEvents, SD>;
/**
* Maximum seconds of inactivity (no messages received or pongs) before the connection is closed.
* Only effective when `sendPingsAutomatically` is `true`.
* Set to `0` to disable.
* @default 120
*/
idleTimeout?: number;
/**
* Whether the server should automatically send WebSocket ping frames to keep
* the connection alive and detect dead clients.
* @default true
*/
sendPingsAutomatically?: boolean;
};
//#endregion
//#region src/interfaces.d.ts
/** Bulk operations for multiple rooms. */
interface ISocketRoomsBulk<TEvents extends SocketEvents> {
/**
* Events that can be emitted to multiple rooms at once.
*
* **Recommended pattern:** Use a union of `{ rooms: R; event: T }` objects:
*
* @example
* interface MyEvents extends SocketEvents {
* emitRooms:
* | { rooms: ['room1', 'room2']; event: { 'alert': { msg: string } } }
* | { rooms: ['roomA', 'roomB']; event: { 'message': { text: string } } };
*
* socket.rooms.bulk.emit(["room1", "room2"], "alert", { msg: "Hello" });
* }
*/
emit: <Rs extends NonNullable<TEvents["emitRooms"]>["rooms"], E extends StringNumberKeys<EventsForRooms<NonNullable<TEvents["emitRooms"]>, Rs>>, D extends NonNullable<EventsForRooms<NonNullable<TEvents["emitRooms"]>, Rs>>[E]>(rooms: Rs, event: E, data: D) => this;
/**
* Join multiple rooms.
* @example socket.rooms.bulk.join(["lobby", "notifications"]);
*/
join: (rooms: string[]) => this;
/**
* Leave multiple rooms.
* @example socket.rooms.bulk.leave(["lobby", "notifications"]);
*/
leave: (rooms: string[]) => this;
}
/**
* Room API available on individual socket instances (client-side or server-side socket).
* Provides methods to join/leave rooms and emit to rooms.
*
* @typeParam TEvents - The socket events definition.
*/
interface ISocketRooms<TEvents extends SocketEvents> {
/**
* Publishes a raw message to a specific room without applying any serialization or encoding.
*
* This method is useful for sending custom protocol messages or pre-encoded data directly
* to all sockets subscribed to the given room. It bypasses the built-in serialization layer,
* so you are responsible for ensuring that the message format matches what the clients expect.
*
* If the socket has been closed, this method does nothing.
*
* @param room - The name of the room to publish the message to.
* @param message - The raw message to send. Can be a `string` (UTF-8 text) or an `ArrayBuffer` / `Buffer` (binary data).
* @param isBinary - Optional. If `true`, the message is sent as a binary WebSocket frame.
* If `false` or omitted, the frame type is inferred from the type of `message`
* (`string` → text frame, `ArrayBuffer`/`Buffer` → binary frame).
* @param compress - Optional. If `true`, the message will be compressed using the WebSocket
* permessage-deflate extension (if negotiated with the client).
*
* @example
* // Send a JSON string to all sockets in the "lobby" room
* socket.rooms.publishRaw("lobby", JSON.stringify({ type: "announcement", text: "Hello!" }));
*
* @example
* // Send pre-encoded binary data (e.g., MessagePack) to the "game" room
* const packedData = msgpack.encode({ event: "move", x: 10, y: 20 });
* socket.rooms.publishRaw("game", packedData, true);
*/
publishRaw: (room: string, message: ServerOutgoingData, isBinary?: boolean, compress?: boolean) => this;
/**
* Emit a typed event to a specific room (server-side publish).
*
* @typeParam R - Room name (must be a key in `TEvents['emitRoom']`).
* @typeParam E - Event name.
* @typeParam D - Event data type.
* @param room - The target room.
* @param event - The event name.
* @param data - The event payload.
* @returns This server instance (for chaining).
*
* @example socket.rooms.emit("chat", "message", { text: "Hi" });
*/
emit: <R extends StringKeys<TEvents["emitRoom"]>, E extends StringNumberKeys<NonNullable<TEvents["emitRoom"]>[R]>, D extends NonNullable<TEvents["emitRoom"]>[R][E]>(room: R, event: E, data: D) => this;
/**
* Join a single room.
* @example socket.rooms.join("lobby");
*/
join: (room: string) => this;
/**
* Leave a single room.
* @example socket.rooms.leave("lobby");
*/
leave: (room: string) => this;
/**
* Get a list of rooms this socket is currently subscribed to.
* By default, the internal broadcast room is excluded.
*
* @param includeBroadcast - If `true`, includes the broadcast room in the result.
* @returns Array of room names.
*
* @example
* socket.rooms.list(); // ['chat', 'lobby']
* socket.rooms.list(true); // ['chat', 'lobby', '__bytesocket_broadcast__']
*/
list: (includeBroadcast?: boolean) => string[];
/** Bulk operations for multiple rooms. */
bulk: ISocketRoomsBulk<TEvents>;
}
/**
* Public API of an individual WebSocket connection.
*
* @typeParam TEvents - Event map type.
* @typeParam SD - Socket data type (extends `SocketData`).
*/
interface ISocket<TEvents extends SocketEvents = SocketEvents, SD extends SocketData = SocketData> {
/**
* Room management and room-scoped event emission.
*
* @example
* socket.rooms.join("chat");
* socket.rooms.emit("chat", "message", { text: "Hello!" });
* console.log(socket.rooms.list()); // ["chat"]
*/
readonly rooms: ISocketRooms<TEvents>;
/** Unique identifier for the socket (same as `userData.socketKey`). */
readonly id: string;
/**
* Payload attached during successful authentication.
* Available in middleware and event listeners.
*
* @example
* io.on("chat", (socket, data) => {
* console.log(`Message from ${socket.payload.username}`);
* });
*/
payload: any;
/**
* Mutable object for storing arbitrary data during the socket's lifetime.
* Useful for passing data between middleware and event handlers.
*
* @example
* io.use((socket, ctx, next) => {
* socket.locals.requestId = randomUUID();
* next();
* });
*/
locals: any;
/**
* Whether the socket has completed authentication (or auth is disabled).
* Returns `true` if no auth is configured, or if authentication succeeded.
*/
readonly isAuthenticated: boolean;
/** Whether the socket has been closed. */
readonly isClosed: boolean;
/**
* Whether the socket is currently able to send messages.
* Returns `true` if the WebSocket is open and authentication (if configured) has succeeded.
* Useful for checking readiness before calling `sendRaw()` or `rooms.publishRaw()`.
* No need to use it with `emit()` or `send()` because they already use it under the hood.
*
* @example
* if (socket.canSend) {
* socket.sendRaw('PROTOCOL: custom-v1');
* }
*/
readonly canSend: boolean;
/**
* The user data object attached during the WebSocket upgrade.
* Contains HTTP request headers and other metadata.
*
* @example
* console.log(socket.userData.socketKey);
*/
readonly userData: SD;
/**
* The path component of the URL requested by the client during the
* WebSocket upgrade.
*
* @example
* // If the client connected to `wss://example.com/socket?room=lobby`,
* // this will be `"/socket"`.
*/
readonly url: string;
/**
* The raw query string from the WebSocket upgrade request.
*
* @example
* // If the client connected to `wss://example.com/socket?room=lobby&token=abc`,
* // this will be `"room=lobby&token=abc"`.
* const query = socket.query;
* const params = new URLSearchParams(socket.query);
* console.log(params.get('room')); // "lobby"
*/
readonly query: string;
/**
* The `Cookie` header from the WebSocket upgrade request.
*
* @example
* // Useful for session handling when not using the Authorization header.
* const cookies = socket.cookie;
* const sessionId = parseCookies(cookies)?.sessionId;
*/
readonly cookie: string;
/**
* The `Authorization` header from the WebSocket upgrade request.
* Typically contains a Bearer token or Basic auth credentials.
*
* @example
* const authHeader = socket.authorization;
* if (authHeader?.startsWith('Bearer ')) {
* const token = authHeader.slice(7);
* // validate token...
* }
*/
readonly authorization: string;
/**
* The `User-Agent` header from the WebSocket upgrade request.
*
* @example
* console.log(`Client: ${socket.userAgent}`);
* // "Client: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ..."
*/
readonly userAgent: string;
/**
* The `Host` header from the WebSocket upgrade request.
* Includes the domain and (optionally) port the client used to connect.
*
* @example
* console.log(socket.host); // "api.example.com"
*/
readonly host: string;
/**
* The `X-Forwarded-For` header from the WebSocket upgrade request.
* Contains the originating client IP when behind a proxy or load balancer.
*
* @example
* const clientIp = socket.xForwardedFor?.split(',')[0].trim() || 'unknown';
* console.log(`Client IP: ${clientIp}`);
*/
readonly xForwardedFor: string;
/**
* Emit a typed global event to this socket only.
*
* @typeParam E - Event name (must be a key in `TEvents['emit']`).
* @typeParam D - Event data type.
* @param event - The event name.
* @param data - The event payload.
* @returns This socket instance (for chaining).
*
* @example
* socket.emit("privateMessage", { from: "server", text: "Hello" });
*/
emit<E extends StringNumberKeys<TEvents["emit"]>, D extends NonNullable<TEvents["emit"]>[E]>(event: E, data: D): this;
/**
* Send a raw message (string or binary) directly to this socket.
* Bypasses serialization. Useful for custom protocols.
*
* @param message - The message to send.
* @param isBinary - Whether to send as binary frame.
* @default true `if message is not a string`.
* @param compress - Whether to use permessage-deflate compression.
* @returns This socket instance.
*
* @example
* socket.sendRaw(JSON.stringify({ custom: "data" }));
*/
sendRaw(message: ServerOutgoingData, isBinary?: boolean, compress?: boolean): this;
/**
* Send any lifecycle or user message to this socket.
* Automatically encodes according to the configured serialization.
* You typically use `emit()` or `broadcast()` instead.
*
* @param payload - The message to send (user message or lifecycle message).
* @returns This socket instance.
*
* @example
* socket.send({ event: "echo", data: { message: "hello" } });
*/
send<R extends string, E extends string | number, D>(payload: LifecycleMessage<R, D> | UserMessage<R, E, D>): this;
/**
* Broadcast a global event to all **other** connected sockets.
* The publishing socket does **not** receive the message.
*
* @typeParam E - Event name.
* @typeParam D - Event data type.
* @param event - The event name.
* @param data - The event payload.
* @returns This socket instance.
*
* @example
* socket.broadcast("userJoined", { userId: socket.id });
*/
broadcast<E extends StringNumberKeys<TEvents["emit"]>, D extends NonNullable<TEvents["emit"]>[E]>(event: E, data: D): this;
/**
* Close the WebSocket connection gracefully.
*
* @param code - WebSocket close code. @default 1000
* @param reason - Close reason string. @default "normal"
*
* @example
* socket.close(1008, "Policy violation");
*/
close(code?: number, reason?: string): void;
/**
* Handle an incoming auth message. Sets up timeout, calls user-provided auth function,
* and manages the success/failure lifecycle.
*
* @internal
*/
_handleAuth<D>(parsed: {
type: LifecycleTypes.auth;
data: D;
} | null, auth: AuthFunction<TEvents, SD, D> | undefined, authTimeout: number, next: MiddlewareNext): void;
}
/**
* Lifecycle event API available on the ByteSocket server instance.
* Allows listening to connection, authentication, message, close, and error events.
*
* @typeParam TEvents - The socket events definition.
* @typeParam SD - The socket data type.
*/
interface ILifecycleServer<TEvents extends SocketEvents, SD extends SocketData, UpgradeCallback extends AnyCallback> {
/** Register a listener for the HTTP upgrade phase. */
onUpgrade: (callback: UpgradeCallback) => this;
/** Remove a listener for the HTTP upgrade phase. */
offUpgrade: (callback?: UpgradeCallback) => this;
/** Register a one-time listener for the HTTP upgrade phase. */
onceUpgrade: (callback: UpgradeCallback) => this;
/** Register a listener for socket open (after successful auth). */
onOpen: (callback: (socket: ISocket<TEvents, SD>) => void) => this;
/** Remove a listener for socket open. */
offOpen: (callback?: (socket: ISocket<TEvents, SD>) => void) => this;
/** Register a one-time listener for socket open. */
onceOpen: (callback: (socket: ISocket<TEvents, SD>) => void) => this;
/** Register a listener for authentication success. */
onAuthSuccess: (callback: (socket: ISocket<TEvents, SD>) => void) => this;
/** Remove a listener for authentication success. */
offAuthSuccess: (callback?: (socket: ISocket<TEvents, SD>) => void) => this;
/** Register a one-time listener for authentication success. */
onceAuthSuccess: (callback: (socket: ISocket<TEvents, SD>) => void) => this;
/** Register a listener for authentication failure. */
onAuthError: (callback: (socket: ISocket<TEvents, SD>, ctx: ErrorContext) => void) => this;
/** Remove a listener for authentication failure. */
offAuthError: (callback?: (socket: ISocket<TEvents, SD>, ctx: ErrorContext) => void) => this;
/** Register a one-time listener for authentication failure. */
onceAuthError: (callback: (socket: ISocket<TEvents, SD>, ctx: ErrorContext) => void) => this;
/** Register a listener for raw incoming messages. */
onMessage: (callback: (socket: ISocket<TEvents, SD>, data: ServerIncomingData, isBinary: boolean) => void) => this;
/** Remove a listener for raw incoming messages. */
offMessage: (callback?: (socket: ISocket<TEvents, SD>, data: ServerIncomingData, isBinary: boolean) => void) => this;
/** Register a one-time listener for raw incoming messages. */
onceMessage: (callback: (socket: ISocket<TEvents, SD>, data: ServerIncomingData, isBinary: boolean) => void) => this;
/** Register a listener for socket close. */
onClose: (callback: (socket: ISocket<TEvents, SD>, code: number, reason: ServerIncomingData) => void) => this;
/** Remove a listener for socket close. */
offClose: (callback?: (socket: ISocket<TEvents, SD>, code: number, reason: ServerIncomingData) => void) => this;
/** Register a one-time listener for socket close. */
onceClose: (callback: (socket: ISocket<TEvents, SD>, code: number, reason: ServerIncomingData) => void) => this;
/** Register a listener for errors. */
onError: (callback: (socket: ISocket<TEvents, SD> | null, ctx: ErrorContext) => void) => this;
/** Remove a listener for errors. */
offError: (callback?: (socket: ISocket<TEvents, SD> | null, ctx: ErrorContext) => void) => this;
/** Register a one-time listener for errors. */
onceError: (callback: (socket: ISocket<TEvents, SD> | null, ctx: ErrorContext) => void) => this;
}
/** Lifecycle hooks for room join/leave (single rooms). */
interface IRoomsLifecycleServer<TEvents extends SocketEvents, SD extends SocketData> {
/**
* Register a guard for single room join requests.
* Call `next()` to allow, `next(error)` to reject.
*
* @example
* io.rooms.lifecycle.onJoin((socket, room, next) => {
* if (room === 'admin' && !socket.payload?.isAdmin) {
* next(new Error('Not authorized'));
* } else {
* next();
* }
* });
*/
onJoin: (callback: (socket: ISocket<TEvents, SD>, room: string, next: MiddlewareNext) => void) => this;
/** Remove a guard for single room join requests. */
offJoin: (callback?: (socket: ISocket<TEvents, SD>, room: string, next: MiddlewareNext) => void) => this;
/** Register a one-time guard for single room join requests. */
onceJoin: (callback: (socket: ISocket<TEvents, SD>, room: string, next: MiddlewareNext) => void) => this;
/** Register a guard for single room leave requests. */
onLeave: (callback: (socket: ISocket<TEvents, SD>, room: string, next: MiddlewareNext) => void) => this;
/** Remove a guard for single room leave requests. */
offLeave: (callback?: (socket: ISocket<TEvents, SD>, room: string, next: MiddlewareNext) => void) => this;
/** Register a one-time guard for single room leave requests. */
onceLeave: (callback: (socket: ISocket<TEvents, SD>, room: string, next: MiddlewareNext) => void) => this;
}
/** Lifecycle hooks for bulk room operations. */
interface IRoomsBulkLifecycleServer<TEvents extends SocketEvents, SD extends SocketData> {
/** Register a guard for bulk room join requests. */
onJoin: (callback: (socket: ISocket<TEvents, SD>, rooms: string[], next: MiddlewareNext) => void) => this;
/** Remove a guard for bulk room join requests. */
offJoin: (callback?: (socket: ISocket<TEvents, SD>, rooms: string[], next: MiddlewareNext) => void) => this;
/** Register a one-time guard for bulk room join requests. */
onceJoin: (callback: (socket: ISocket<TEvents, SD>, rooms: string[], next: MiddlewareNext) => void) => this;
/** Register a guard for bulk room leave requests. */
onLeave: (callback: (socket: ISocket<TEvents, SD>, rooms: string[], next: MiddlewareNext) => void) => this;
/** Remove a guard for bulk room leave requests. */
offLeave: (callback?: (socket: ISocket<TEvents, SD>, rooms: string[], next: MiddlewareNext) => void) => this;
/** Register a one-time guard for bulk room leave requests. */
onceLeave: (callback: (socket: ISocket<TEvents, SD>, rooms: string[], next: MiddlewareNext) => void) => this;
}
interface IRoomsBulkServer<TEvents extends SocketEvents, SD extends SocketData> {
/**
* Emit a typed event to multiple rooms at once.
*
* @typeParam Rs - The array of room names.
* @typeParam E - Event name.
* @typeParam D - Event data type.
*
* @example
* interface MyEvents extends SocketEvents {
* emitRooms:
* | { rooms: ['room1', 'room2']; event: { 'alert': { msg: string } } }
* | { rooms: ['roomA', 'roomB']; event: { 'message': { text: string } } };
*
* io.rooms.bulk.emit(['room1', 'room2'], 'alert', { msg: 'Hello both!' });
*/
emit: <Rs extends NonNullable<TEvents["emitRooms"]>["rooms"], E extends StringNumberKeys<EventsForRooms<NonNullable<TEvents["emitRooms"]>, Rs>>, D extends NonNullable<EventsForRooms<NonNullable<TEvents["emitRooms"]>, Rs>>[E]>(rooms: Rs, event: E, data: D) => this;
/** Lifecycle hooks for bulk room operations. */
lifecycle: IRoomsBulkLifecycleServer<TEvents, SD>;
}
/**
* Room management API available on the ByteSocket server instance.
* Provides methods to emit to rooms, publish raw data, and attach room-level middleware.
*
* @typeParam TEvents - The socket events definition.
* @typeParam SD - The socket data type.
*/
interface IRoomsServer<TEvents extends SocketEvents, SD extends SocketData> {
/**
* Publishes a raw message to all sockets subscribed to the given room.
*
* This method broadcasts the data directly to all connected sockets in the room
* using the underlying `ws` server, **without** applying any encoding,
* serialization, or lifecycle processing. It is useful for broadcasting
* custom-formatted messages, pre-encoded payloads, or implementing custom protocols.
*
* If the server instance has been destroyed, this method does nothing.
*
* @param room - The room name to publish the message to. All sockets that have joined this
* room (including the global broadcast room) will receive the message.
* @param message - The raw data to send. Accepts a `string` (sent as a UTF-8 text frame) or
* an `ArrayBuffer` / `Buffer` (sent as a binary frame).
* @param isBinary - Optional. If `true`, forces the message to be sent as a binary WebSocket
* frame. If `false` or omitted, the frame type is inferred from the type of
* `message` (`string` → text, `ArrayBuffer`/`Buffer` → binary).
* @param compress - Optional. If `true`, the message will be compressed using the WebSocket
* permessage-deflate extension (if negotiated with the clients).
*
* @example
* // Broadcast a JSON string to the "lobby" room
* io.rooms.publishRaw("lobby", JSON.stringify({ type: "announcement", text: "Server restart in 5m" }));
*
* @example
* // Broadcast pre-encoded MessagePack data to the "lobby" room
* const packed = msgpack.encode({ event: "system", status: "ok" });
* io.rooms.publishRaw("lobby", packed, true);
*
* @example
* // Send compressed binary data
* const buffer = new Uint8Array([1, 2, 3]);
* io.rooms.publishRaw("updates", buffer, true, true);
*/
publishRaw: (room: string, message: ServerOutgoingData, isBinary?: boolean, compress?: boolean) => this;
/**
* Emit a typed event to a specific room (server-side publish).
*
* @typeParam R - Room name (must be a key in `TEvents['emitRoom']`).
* @typeParam E - Event name.
* @typeParam D - Event data type.
*
* @example
* io.rooms.emit('chat', 'message', { text: 'Hello everyone' });
*/
emit: <R extends StringKeys<TEvents["emitRoom"]>, E extends StringNumberKeys<NonNullable<TEvents["emitRoom"]>[R]>, D extends NonNullable<TEvents["emitRoom"]>[R][E]>(room: R, event: E, data: D) => this;
/** Register a room event middleware. */
on: <R extends StringKeys<TEvents["listenRoom"]>, E extends StringNumberKeys<NonNullable<TEvents["listenRoom"]>[R]>, D extends NonNullable<TEvents["listenRoom"]>[R][E]>(room: R, event: E, callback: RoomEventMiddleware<TEvents, SD, D>) => this;
/** Remove a room event middleware. */
off: <R extends StringKeys<TEvents["listenRoom"]>, E extends StringNumberKeys<NonNullable<TEvents["listenRoom"]>[R]>, D extends NonNullable<TEvents["listenRoom"]>[R][E]>(room: R, event?: E, callback?: RoomEventMiddleware<TEvents, SD, D>) => this;
/** Register a one-time room event middleware. */
once: <R extends StringKeys<TEvents["listenRoom"]>, E extends StringNumberKeys<NonNullable<TEvents["listenRoom"]>[R]>, D extends NonNullable<TEvents["listenRoom"]>[R][E]>(room: R, event: E, callback: RoomEventMiddleware<TEvents, SD, D>) => this;
/** Lifecycle hooks for room join/leave (single rooms). */
lifecycle: IRoomsLifecycleServer<TEvents, SD>;
/** Bulk operations for multiple rooms. */
bulk: IRoomsBulkServer<TEvents, SD>;
}
/**
* Public API of a ByteSocket server instance.
*
* Manages WebSocket connections, rooms, middleware, and event routing.
* The implementation class {@link ByteSocket} should `implement` this interface.
*
* @typeParam TEvents - Event map (extends `SocketEvents`) defining the shape of
* all emit/listen events (global and room‑scoped).
* @typeParam SD - Socket data type that extends `SocketData`.
*/
interface IByteSocket<TEvents extends SocketEvents = SocketEvents, SD extends SocketData = SocketData, UpgradeCallback extends AnyCallback = AnyCallback> extends IByteSocketBase {
/**
* Lifecycle event listeners for connection, authentication, and errors.
*
* @example
* io.lifecycle.onOpen((socket) => console.log('Connected!'));
* io.lifecycle.onAuthError((socket, ctx) => console.error('Auth failed', ctx.error));
* io.lifecycle.onClose((socket, code, msg) => console.log('Closed', code));
*/
readonly lifecycle: ILifecycleServer<TEvents, SD, UpgradeCallback>;
/**
* Room management, room-scoped event emission, and room lifecycle hooks.
*
* @example
* io.rooms.emit('lobby', 'announcement', { text: 'Welcome!' });
* io.rooms.on('chat', 'message', (socket, data, next) => { ... });
* io.rooms.lifecycle.onJoin((socket, room, next) => {
* if (room === 'admin') next(new Error('Not allowed'));
* else next();
* });
*/
readonly rooms: IRoomsServer<TEvents, SD>;
/**
* Map of all currently connected sockets, keyed by socket ID.
*
* **Do not modify this map directly** - it is managed internally.
*
* @example
* for (const [id, socket] of io.sockets) {
* socket.emit('ping', undefined);
* }
*/
readonly sockets: Map<string, ISocket<TEvents, SD>>;
/**
* Indicates whether the server instance has been permanently destroyed.
*
* Once `true`, the instance cannot be reused; all connections have been closed and
* internal resources released. Use {@link destroy} to initiate shutdown.
*
* @example
* if (io.destroyed) {
* console.log('Server is shut down');
* }
*/
readonly destroyed: boolean;
/**
* Emit a global event to all connected sockets.
*
* @typeParam E - Event name (must be a key in `TEvents['emit']`).
* @typeParam D - Event data type.
*
* @example io.emit('userJoined', { userId: '123' });
*/
emit<E extends StringNumberKeys<TEvents["emit"]>, D extends NonNullable<TEvents["emit"]>[E]>(event: E, data: D): this;
/**
* Register a permanent listener for global events.
*
* @typeParam E - Event name (must be a key in `TEvents['listen']`).
*
* @example io.on('userJoined', (socket, data) => { console.log(data.userId); });
*/
on<E extends StringNumberKeys<TEvents["listen"]>, D extends NonNullable<TEvents["listen"]>[E]>(event: E, callback: EventCallback<TEvents, SD, D>): this;
/**
* Remove a listener for global events.
* If no callback is provided, **all** listeners for that event are removed.
*
* @example io.off('userJoined', myCallback);
*/
off<E extends StringNumberKeys<TEvents["listen"]>, D extends NonNullable<TEvents["listen"]>[E]>(event: E, callback?: EventCallback<TEvents, SD, D>): this;
/**
* Register a one-time listener for a global event.
* The callback is removed after the first invocation.
*
* @example io.once('userJoined', (socket, data) => { console.log('First join'); });
*/
once<E extends StringNumberKeys<TEvents["listen"]>, D extends NonNullable<TEvents["listen"]>[E]>(event: E, callback: EventCallback<TEvents, SD, D>): this;
/**
* Register a global middleware function.
* Middleware runs **before** any user message is processed.
*
* @example
* io.use((socket, ctx, next) => {
* console.log('Message received:', ctx);
* next();
* });
*/
use(fn: Middleware<TEvents, SD>): this;
attach(server: unknown, path: string): this;
destroy(): void;
}
//#endregion
//#region src/byte-socket-server-base.d.ts
type RequiredOptions = "middlewareTimeout" | "roomMiddlewareTimeout" | "authTimeout" | "broadcastRoom" | "onMiddlewareError" | "onMiddlewareTimeout" | "idleTimeout" | "sendPingsAutomatically";
declare abstract class ByteSocketServerBase<TEvents extends SocketEvents = SocketEvents, SD extends SocketData = SocketData, UpgradeCallback extends AnyCallback = AnyCallback> extends ByteSocketBase implements IByteSocket<TEvents, SD, UpgradeCallback> {
#private;
readonly lifecycle: ILifecycleServer<TEvents, SD, UpgradeCallback>;
readonly rooms: IRoomsServer<TEvents, SD>;
readonly sockets: Map<string, ISocket<TEvents, SD>>;
protected options: Omit<ByteSocketOptionsBase<TEvents, SD>, RequiredOptions | "debug" | "serialization" | "msgpackrOptions"> & Pick<Required<ByteSocketOptionsBase<TEvents, SD>>, RequiredOptions>;
constructor(options?: ByteSocketOptionsBase<TEvents, SD>);
abstract attach(server: unknown, path: string): this;
abstract destroy(): void;
protected abstract publishRaw(room: string, message: ServerOutgoingData, isBinary?: boolean, compress?: boolean): typeof this.rooms;
protected _destroy(): void;
emit<E extends StringNumberKeys<TEvents["emit"]>, D extends NonNullable<TEvents["emit"]>[E]>(event: E, data: D): this;
on<E extends StringNumberKeys<TEvents["listen"]>, D extends NonNullable<TEvents["listen"]>[E]>(event: E, callback: EventCallback<TEvents, SD, D>): this;
off<E extends StringNumberKeys<TEvents["listen"]>, D extends NonNullable<TEvents["listen"]>[E]>(event: E, callback?: EventCallback<TEvents, SD, D>): this;
once<E extends StringNumberKeys<TEvents["listen"]>, D extends NonNullable<TEvents["listen"]>[E]>(event: E, callback: EventCallback<TEvents, SD, D>): this;
use(fn: Middleware<TEvents, SD>): this;
get destroyed(): boolean;
protected message(socket: ISocket<TEvents, SD>, message: ServerIncomingData, isBinary: boolean): void;
protected close(socket: ISocket<TEvents, SD>, code: number, reason: Buffer | ArrayBuffer): void;
protected _runSyncHooks<Args extends Array<unknown>>(callbackSet: Set<AnyCallback> | undefined, args: Args, next: MiddlewareNext): void;
}
//#endregion
export { RoomEventMiddleware as _, IRoomsBulkServer as a, SocketData as b, ISocket as c, AuthCallback as d, AuthFunction as f, MiddlewareNext as g, Middleware as h, IRoomsBulkLifecycleServer as i, ISocketRooms as l, EventCallback as m, IByteSocket as n, IRoomsLifecycleServer as o, ByteSocketOptionsBase as p, ILifecycleServer as r, IRoomsServer as s, ByteSocketServerBase as t, ISocketRoomsBulk as u, ServerIncomingData as v, ServerOutgoingData as y };
//# sourceMappingURL=byte-socket-server-base-CLZDN4De.d.cts.map
{"version":3,"file":"byte-socket-server-base-CLZDN4De.d.cts","names":[],"sources":["../src/types.ts","../src/interfaces.ts","../src/byte-socket-server-base.ts"],"mappings":"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"}
import { AnyCallback, ByteSocketBase, ErrorContext, EventsForRooms, IByteSocketBase, LifecycleMessage, LifecycleTypes, MsgpackrOptions, SocketEvents, StringKeys, StringNumberKeys, UserMessage } from "@bytesocket/core";
import { UUID } from "node:crypto";
//#region src/types.d.ts
/** The data types actually received from outside.*/
type ServerIncomingData = Buffer | ArrayBuffer | Uint8Array;
/** The data types actually accepted by the server `server.send()` or `ws.send()` methods.*/
type ServerOutgoingData = string | ServerIncomingData;
/**
* Callback used by the authentication function to return the authentication result.
* @param payload - The authenticated user data to attach to the socket.
* @param error - Optional error if authentication failed.
*/
type AuthCallback = (payload: any, error?: Error) => void;
/**
* Authentication function signature. Called when a client sends an auth message.
*
* @typeParam SD - The socket data type (must extend `SocketData`).
* @typeParam D - The type of the authentication data sent by the client.
*
* @example
* const auth: AuthFunction = (socket, data, callback) => {
* if (data.token === "secret") {
* callback({ userId: 1 });
* } else {
* callback(null, new Error("Invalid token"));
* }
* };
*/
type AuthFunction<TEvents extends SocketEvents, SD extends SocketData, D = any> = (socket: ISocket<TEvents, SD>, data: D, callback: AuthCallback) => void;
/**
* Callback for global event listeners.
*
* @typeParam SD - The socket data type.
* @typeParam D - The type of the event data.
*
* @example
* socket.on("userJoined", (socket, data) => {
* console.log(`User ${data.userId} joined`);
* });
*/
type EventCallback<TEvents extends SocketEvents, SD extends SocketData, D> = (socket: ISocket<TEvents, SD>, data: D) => void;
/**
* Middleware function for room-scoped events. Can inspect or block the broadcast.
*
* @typeParam SD - The socket data type.
* @typeParam D - The type of the event data.
*
* @example
* io.rooms.on("chat", "message", (socket, data, next) => {
* if (data.text.includes("badword")) {
* next(new Error("Profanity not allowed"));
* } else {
* next();
* }
* });
*
* // Also supports async functions / Promises
* io.rooms.on("chat", "message", async (socket, data, next) => {
* const isValid = await validateMessage(data);
* if (!isValid) {
* return next(new Error("Invalid"));
* }
* next();
* });
*/
type RoomEventMiddleware<TEvents extends SocketEvents, SD extends SocketData, D> = (socket: ISocket<TEvents, SD>, data: D, next: MiddlewareNext) => void | Promise<void>;
/** Next function for middleware chains. Call `next()` to proceed, or `next(error)` to abort. */
type MiddlewareNext = (error?: unknown | null) => void;
/**
* Global middleware function. Runs before any user message is processed.
*
* @typeParam SD - The socket data type.
*
* @example
* io.use((socket, ctx, next) => {
* console.log("Received:", ctx);
* next();
* });
*/
type Middleware<TEvents extends SocketEvents = SocketEvents, SD extends SocketData = SocketData> = (socket: ISocket<TEvents, SD>, ctx: UserMessage, next: MiddlewareNext) => void | Promise<void>;
/**
* Data automatically attached to every socket by the server.
* Contains HTTP request information available during the WebSocket upgrade.
*/
type SocketData = {
/** Unique identifier for the socket (UUID v4). */socketKey: UUID; /** The url string from the upgrade request. */
url: string; /** The query string from the upgrade request. */
query: string; /** The `Host` header value. */
host: string; /** The `Cookie` header value. */
cookie: string; /** The `User-Agent` header value. */
userAgent: string; /** The `Authorization` header value. */
authorization: string; /** The `X-Forwarded-For` header value. */
xForwardedFor: string;
};
/**
* Configuration options for the ByteSocket server.
*
* @typeParam TEvents - The socket events definition.
* @typeParam SD - The socket data type (must extend `SocketData`).
*
* @example
* const io = new ByteSocket({
* debug: true,
* authTimeout: 10000,
* origins: ["https://example.com"],
* serialization: "binary",
* auth: (socket, data, callback) => {
* // validate token
* callback({ userId: 1 });
* }
* });
*/
type ByteSocketOptionsBase<TEvents extends SocketEvents = SocketEvents, SD extends SocketData = SocketData> = {
/** Enable debug logging to console. @default false */debug?: boolean; /** Timeout in milliseconds for global middleware execution. @default 5000 */
middlewareTimeout?: number; /** Timeout in milliseconds for room event middleware execution. @default 5000 */
roomMiddlewareTimeout?: number; /** Timeout for authentication response in milliseconds. @default 5000 */
authTimeout?: number; /** List of allowed origins for CORS. If empty, all origins are allowed. */
origins?: string[]; /** Serialization format: `"json"` or `"binary"` (msgpack). @default "binary" */
serialization?: "json" | "binary"; /** Room name used for global broadcasts. @default "__bytesocket_broadcast__" */
broadcastRoom?: string; /** Options passed directly to the underlying msgpackr Packr instance. */
msgpackrOptions?: MsgpackrOptions; /** Action to take when a global middleware error occurs. @default "ignore" */
onMiddlewareError?: "ignore" | "close" | ((error: unknown, socket: ISocket<TEvents, SD>) => void); /** Action to take when a global middleware times out. @default "ignore" */
onMiddlewareTimeout?: "ignore" | "close" | ((error: unknown, socket: ISocket<TEvents, SD>) => void); /** Authentication configuration. */
auth?: AuthFunction<TEvents, SD>;
/**
* Maximum seconds of inactivity (no messages received or pongs) before the connection is closed.
* Only effective when `sendPingsAutomatically` is `true`.
* Set to `0` to disable.
* @default 120
*/
idleTimeout?: number;
/**
* Whether the server should automatically send WebSocket ping frames to keep
* the connection alive and detect dead clients.
* @default true
*/
sendPingsAutomatically?: boolean;
};
//#endregion
//#region src/interfaces.d.ts
/** Bulk operations for multiple rooms. */
interface ISocketRoomsBulk<TEvents extends SocketEvents> {
/**
* Events that can be emitted to multiple rooms at once.
*
* **Recommended pattern:** Use a union of `{ rooms: R; event: T }` objects:
*
* @example
* interface MyEvents extends SocketEvents {
* emitRooms:
* | { rooms: ['room1', 'room2']; event: { 'alert': { msg: string } } }
* | { rooms: ['roomA', 'roomB']; event: { 'message': { text: string } } };
*
* socket.rooms.bulk.emit(["room1", "room2"], "alert", { msg: "Hello" });
* }
*/
emit: <Rs extends NonNullable<TEvents["emitRooms"]>["rooms"], E extends StringNumberKeys<EventsForRooms<NonNullable<TEvents["emitRooms"]>, Rs>>, D extends NonNullable<EventsForRooms<NonNullable<TEvents["emitRooms"]>, Rs>>[E]>(rooms: Rs, event: E, data: D) => this;
/**
* Join multiple rooms.
* @example socket.rooms.bulk.join(["lobby", "notifications"]);
*/
join: (rooms: string[]) => this;
/**
* Leave multiple rooms.
* @example socket.rooms.bulk.leave(["lobby", "notifications"]);
*/
leave: (rooms: string[]) => this;
}
/**
* Room API available on individual socket instances (client-side or server-side socket).
* Provides methods to join/leave rooms and emit to rooms.
*
* @typeParam TEvents - The socket events definition.
*/
interface ISocketRooms<TEvents extends SocketEvents> {
/**
* Publishes a raw message to a specific room without applying any serialization or encoding.
*
* This method is useful for sending custom protocol messages or pre-encoded data directly
* to all sockets subscribed to the given room. It bypasses the built-in serialization layer,
* so you are responsible for ensuring that the message format matches what the clients expect.
*
* If the socket has been closed, this method does nothing.
*
* @param room - The name of the room to publish the message to.
* @param message - The raw message to send. Can be a `string` (UTF-8 text) or an `ArrayBuffer` / `Buffer` (binary data).
* @param isBinary - Optional. If `true`, the message is sent as a binary WebSocket frame.
* If `false` or omitted, the frame type is inferred from the type of `message`
* (`string` → text frame, `ArrayBuffer`/`Buffer` → binary frame).
* @param compress - Optional. If `true`, the message will be compressed using the WebSocket
* permessage-deflate extension (if negotiated with the client).
*
* @example
* // Send a JSON string to all sockets in the "lobby" room
* socket.rooms.publishRaw("lobby", JSON.stringify({ type: "announcement", text: "Hello!" }));
*
* @example
* // Send pre-encoded binary data (e.g., MessagePack) to the "game" room
* const packedData = msgpack.encode({ event: "move", x: 10, y: 20 });
* socket.rooms.publishRaw("game", packedData, true);
*/
publishRaw: (room: string, message: ServerOutgoingData, isBinary?: boolean, compress?: boolean) => this;
/**
* Emit a typed event to a specific room (server-side publish).
*
* @typeParam R - Room name (must be a key in `TEvents['emitRoom']`).
* @typeParam E - Event name.
* @typeParam D - Event data type.
* @param room - The target room.
* @param event - The event name.
* @param data - The event payload.
* @returns This server instance (for chaining).
*
* @example socket.rooms.emit("chat", "message", { text: "Hi" });
*/
emit: <R extends StringKeys<TEvents["emitRoom"]>, E extends StringNumberKeys<NonNullable<TEvents["emitRoom"]>[R]>, D extends NonNullable<TEvents["emitRoom"]>[R][E]>(room: R, event: E, data: D) => this;
/**
* Join a single room.
* @example socket.rooms.join("lobby");
*/
join: (room: string) => this;
/**
* Leave a single room.
* @example socket.rooms.leave("lobby");
*/
leave: (room: string) => this;
/**
* Get a list of rooms this socket is currently subscribed to.
* By default, the internal broadcast room is excluded.
*
* @param includeBroadcast - If `true`, includes the broadcast room in the result.
* @returns Array of room names.
*
* @example
* socket.rooms.list(); // ['chat', 'lobby']
* socket.rooms.list(true); // ['chat', 'lobby', '__bytesocket_broadcast__']
*/
list: (includeBroadcast?: boolean) => string[];
/** Bulk operations for multiple rooms. */
bulk: ISocketRoomsBulk<TEvents>;
}
/**
* Public API of an individual WebSocket connection.
*
* @typeParam TEvents - Event map type.
* @typeParam SD - Socket data type (extends `SocketData`).
*/
interface ISocket<TEvents extends SocketEvents = SocketEvents, SD extends SocketData = SocketData> {
/**
* Room management and room-scoped event emission.
*
* @example
* socket.rooms.join("chat");
* socket.rooms.emit("chat", "message", { text: "Hello!" });
* console.log(socket.rooms.list()); // ["chat"]
*/
readonly rooms: ISocketRooms<TEvents>;
/** Unique identifier for the socket (same as `userData.socketKey`). */
readonly id: string;
/**
* Payload attached during successful authentication.
* Available in middleware and event listeners.
*
* @example
* io.on("chat", (socket, data) => {
* console.log(`Message from ${socket.payload.username}`);
* });
*/
payload: any;
/**
* Mutable object for storing arbitrary data during the socket's lifetime.
* Useful for passing data between middleware and event handlers.
*
* @example
* io.use((socket, ctx, next) => {
* socket.locals.requestId = randomUUID();
* next();
* });
*/
locals: any;
/**
* Whether the socket has completed authentication (or auth is disabled).
* Returns `true` if no auth is configured, or if authentication succeeded.
*/
readonly isAuthenticated: boolean;
/** Whether the socket has been closed. */
readonly isClosed: boolean;
/**
* Whether the socket is currently able to send messages.
* Returns `true` if the WebSocket is open and authentication (if configured) has succeeded.
* Useful for checking readiness before calling `sendRaw()` or `rooms.publishRaw()`.
* No need to use it with `emit()` or `send()` because they already use it under the hood.
*
* @example
* if (socket.canSend) {
* socket.sendRaw('PROTOCOL: custom-v1');
* }
*/
readonly canSend: boolean;
/**
* The user data object attached during the WebSocket upgrade.
* Contains HTTP request headers and other metadata.
*
* @example
* console.log(socket.userData.socketKey);
*/
readonly userData: SD;
/**
* The path component of the URL requested by the client during the
* WebSocket upgrade.
*
* @example
* // If the client connected to `wss://example.com/socket?room=lobby`,
* // this will be `"/socket"`.
*/
readonly url: string;
/**
* The raw query string from the WebSocket upgrade request.
*
* @example
* // If the client connected to `wss://example.com/socket?room=lobby&token=abc`,
* // this will be `"room=lobby&token=abc"`.
* const query = socket.query;
* const params = new URLSearchParams(socket.query);
* console.log(params.get('room')); // "lobby"
*/
readonly query: string;
/**
* The `Cookie` header from the WebSocket upgrade request.
*
* @example
* // Useful for session handling when not using the Authorization header.
* const cookies = socket.cookie;
* const sessionId = parseCookies(cookies)?.sessionId;
*/
readonly cookie: string;
/**
* The `Authorization` header from the WebSocket upgrade request.
* Typically contains a Bearer token or Basic auth credentials.
*
* @example
* const authHeader = socket.authorization;
* if (authHeader?.startsWith('Bearer ')) {
* const token = authHeader.slice(7);
* // validate token...
* }
*/
readonly authorization: string;
/**
* The `User-Agent` header from the WebSocket upgrade request.
*
* @example
* console.log(`Client: ${socket.userAgent}`);
* // "Client: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ..."
*/
readonly userAgent: string;
/**
* The `Host` header from the WebSocket upgrade request.
* Includes the domain and (optionally) port the client used to connect.
*
* @example
* console.log(socket.host); // "api.example.com"
*/
readonly host: string;
/**
* The `X-Forwarded-For` header from the WebSocket upgrade request.
* Contains the originating client IP when behind a proxy or load balancer.
*
* @example
* const clientIp = socket.xForwardedFor?.split(',')[0].trim() || 'unknown';
* console.log(`Client IP: ${clientIp}`);
*/
readonly xForwardedFor: string;
/**
* Emit a typed global event to this socket only.
*
* @typeParam E - Event name (must be a key in `TEvents['emit']`).
* @typeParam D - Event data type.
* @param event - The event name.
* @param data - The event payload.
* @returns This socket instance (for chaining).
*
* @example
* socket.emit("privateMessage", { from: "server", text: "Hello" });
*/
emit<E extends StringNumberKeys<TEvents["emit"]>, D extends NonNullable<TEvents["emit"]>[E]>(event: E, data: D): this;
/**
* Send a raw message (string or binary) directly to this socket.
* Bypasses serialization. Useful for custom protocols.
*
* @param message - The message to send.
* @param isBinary - Whether to send as binary frame.
* @default true `if message is not a string`.
* @param compress - Whether to use permessage-deflate compression.
* @returns This socket instance.
*
* @example
* socket.sendRaw(JSON.stringify({ custom: "data" }));
*/
sendRaw(message: ServerOutgoingData, isBinary?: boolean, compress?: boolean): this;
/**
* Send any lifecycle or user message to this socket.
* Automatically encodes according to the configured serialization.
* You typically use `emit()` or `broadcast()` instead.
*
* @param payload - The message to send (user message or lifecycle message).
* @returns This socket instance.
*
* @example
* socket.send({ event: "echo", data: { message: "hello" } });
*/
send<R extends string, E extends string | number, D>(payload: LifecycleMessage<R, D> | UserMessage<R, E, D>): this;
/**
* Broadcast a global event to all **other** connected sockets.
* The publishing socket does **not** receive the message.
*
* @typeParam E - Event name.
* @typeParam D - Event data type.
* @param event - The event name.
* @param data - The event payload.
* @returns This socket instance.
*
* @example
* socket.broadcast("userJoined", { userId: socket.id });
*/
broadcast<E extends StringNumberKeys<TEvents["emit"]>, D extends NonNullable<TEvents["emit"]>[E]>(event: E, data: D): this;
/**
* Close the WebSocket connection gracefully.
*
* @param code - WebSocket close code. @default 1000
* @param reason - Close reason string. @default "normal"
*
* @example
* socket.close(1008, "Policy violation");
*/
close(code?: number, reason?: string): void;
/**
* Handle an incoming auth message. Sets up timeout, calls user-provided auth function,
* and manages the success/failure lifecycle.
*
* @internal
*/
_handleAuth<D>(parsed: {
type: LifecycleTypes.auth;
data: D;
} | null, auth: AuthFunction<TEvents, SD, D> | undefined, authTimeout: number, next: MiddlewareNext): void;
}
/**
* Lifecycle event API available on the ByteSocket server instance.
* Allows listening to connection, authentication, message, close, and error events.
*
* @typeParam TEvents - The socket events definition.
* @typeParam SD - The socket data type.
*/
interface ILifecycleServer<TEvents extends SocketEvents, SD extends SocketData, UpgradeCallback extends AnyCallback> {
/** Register a listener for the HTTP upgrade phase. */
onUpgrade: (callback: UpgradeCallback) => this;
/** Remove a listener for the HTTP upgrade phase. */
offUpgrade: (callback?: UpgradeCallback) => this;
/** Register a one-time listener for the HTTP upgrade phase. */
onceUpgrade: (callback: UpgradeCallback) => this;
/** Register a listener for socket open (after successful auth). */
onOpen: (callback: (socket: ISocket<TEvents, SD>) => void) => this;
/** Remove a listener for socket open. */
offOpen: (callback?: (socket: ISocket<TEvents, SD>) => void) => this;
/** Register a one-time listener for socket open. */
onceOpen: (callback: (socket: ISocket<TEvents, SD>) => void) => this;
/** Register a listener for authentication success. */
onAuthSuccess: (callback: (socket: ISocket<TEvents, SD>) => void) => this;
/** Remove a listener for authentication success. */
offAuthSuccess: (callback?: (socket: ISocket<TEvents, SD>) => void) => this;
/** Register a one-time listener for authentication success. */
onceAuthSuccess: (callback: (socket: ISocket<TEvents, SD>) => void) => this;
/** Register a listener for authentication failure. */
onAuthError: (callback: (socket: ISocket<TEvents, SD>, ctx: ErrorContext) => void) => this;
/** Remove a listener for authentication failure. */
offAuthError: (callback?: (socket: ISocket<TEvents, SD>, ctx: ErrorContext) => void) => this;
/** Register a one-time listener for authentication failure. */
onceAuthError: (callback: (socket: ISocket<TEvents, SD>, ctx: ErrorContext) => void) => this;
/** Register a listener for raw incoming messages. */
onMessage: (callback: (socket: ISocket<TEvents, SD>, data: ServerIncomingData, isBinary: boolean) => void) => this;
/** Remove a listener for raw incoming messages. */
offMessage: (callback?: (socket: ISocket<TEvents, SD>, data: ServerIncomingData, isBinary: boolean) => void) => this;
/** Register a one-time listener for raw incoming messages. */
onceMessage: (callback: (socket: ISocket<TEvents, SD>, data: ServerIncomingData, isBinary: boolean) => void) => this;
/** Register a listener for socket close. */
onClose: (callback: (socket: ISocket<TEvents, SD>, code: number, reason: ServerIncomingData) => void) => this;
/** Remove a listener for socket close. */
offClose: (callback?: (socket: ISocket<TEvents, SD>, code: number, reason: ServerIncomingData) => void) => this;
/** Register a one-time listener for socket close. */
onceClose: (callback: (socket: ISocket<TEvents, SD>, code: number, reason: ServerIncomingData) => void) => this;
/** Register a listener for errors. */
onError: (callback: (socket: ISocket<TEvents, SD> | null, ctx: ErrorContext) => void) => this;
/** Remove a listener for errors. */
offError: (callback?: (socket: ISocket<TEvents, SD> | null, ctx: ErrorContext) => void) => this;
/** Register a one-time listener for errors. */
onceError: (callback: (socket: ISocket<TEvents, SD> | null, ctx: ErrorContext) => void) => this;
}
/** Lifecycle hooks for room join/leave (single rooms). */
interface IRoomsLifecycleServer<TEvents extends SocketEvents, SD extends SocketData> {
/**
* Register a guard for single room join requests.
* Call `next()` to allow, `next(error)` to reject.
*
* @example
* io.rooms.lifecycle.onJoin((socket, room, next) => {
* if (room === 'admin' && !socket.payload?.isAdmin) {
* next(new Error('Not authorized'));
* } else {
* next();
* }
* });
*/
onJoin: (callback: (socket: ISocket<TEvents, SD>, room: string, next: MiddlewareNext) => void) => this;
/** Remove a guard for single room join requests. */
offJoin: (callback?: (socket: ISocket<TEvents, SD>, room: string, next: MiddlewareNext) => void) => this;
/** Register a one-time guard for single room join requests. */
onceJoin: (callback: (socket: ISocket<TEvents, SD>, room: string, next: MiddlewareNext) => void) => this;
/** Register a guard for single room leave requests. */
onLeave: (callback: (socket: ISocket<TEvents, SD>, room: string, next: MiddlewareNext) => void) => this;
/** Remove a guard for single room leave requests. */
offLeave: (callback?: (socket: ISocket<TEvents, SD>, room: string, next: MiddlewareNext) => void) => this;
/** Register a one-time guard for single room leave requests. */
onceLeave: (callback: (socket: ISocket<TEvents, SD>, room: string, next: MiddlewareNext) => void) => this;
}
/** Lifecycle hooks for bulk room operations. */
interface IRoomsBulkLifecycleServer<TEvents extends SocketEvents, SD extends SocketData> {
/** Register a guard for bulk room join requests. */
onJoin: (callback: (socket: ISocket<TEvents, SD>, rooms: string[], next: MiddlewareNext) => void) => this;
/** Remove a guard for bulk room join requests. */
offJoin: (callback?: (socket: ISocket<TEvents, SD>, rooms: string[], next: MiddlewareNext) => void) => this;
/** Register a one-time guard for bulk room join requests. */
onceJoin: (callback: (socket: ISocket<TEvents, SD>, rooms: string[], next: MiddlewareNext) => void) => this;
/** Register a guard for bulk room leave requests. */
onLeave: (callback: (socket: ISocket<TEvents, SD>, rooms: string[], next: MiddlewareNext) => void) => this;
/** Remove a guard for bulk room leave requests. */
offLeave: (callback?: (socket: ISocket<TEvents, SD>, rooms: string[], next: MiddlewareNext) => void) => this;
/** Register a one-time guard for bulk room leave requests. */
onceLeave: (callback: (socket: ISocket<TEvents, SD>, rooms: string[], next: MiddlewareNext) => void) => this;
}
interface IRoomsBulkServer<TEvents extends SocketEvents, SD extends SocketData> {
/**
* Emit a typed event to multiple rooms at once.
*
* @typeParam Rs - The array of room names.
* @typeParam E - Event name.
* @typeParam D - Event data type.
*
* @example
* interface MyEvents extends SocketEvents {
* emitRooms:
* | { rooms: ['room1', 'room2']; event: { 'alert': { msg: string } } }
* | { rooms: ['roomA', 'roomB']; event: { 'message': { text: string } } };
*
* io.rooms.bulk.emit(['room1', 'room2'], 'alert', { msg: 'Hello both!' });
*/
emit: <Rs extends NonNullable<TEvents["emitRooms"]>["rooms"], E extends StringNumberKeys<EventsForRooms<NonNullable<TEvents["emitRooms"]>, Rs>>, D extends NonNullable<EventsForRooms<NonNullable<TEvents["emitRooms"]>, Rs>>[E]>(rooms: Rs, event: E, data: D) => this;
/** Lifecycle hooks for bulk room operations. */
lifecycle: IRoomsBulkLifecycleServer<TEvents, SD>;
}
/**
* Room management API available on the ByteSocket server instance.
* Provides methods to emit to rooms, publish raw data, and attach room-level middleware.
*
* @typeParam TEvents - The socket events definition.
* @typeParam SD - The socket data type.
*/
interface IRoomsServer<TEvents extends SocketEvents, SD extends SocketData> {
/**
* Publishes a raw message to all sockets subscribed to the given room.
*
* This method broadcasts the data directly to all connected sockets in the room
* using the underlying `ws` server, **without** applying any encoding,
* serialization, or lifecycle processing. It is useful for broadcasting
* custom-formatted messages, pre-encoded payloads, or implementing custom protocols.
*
* If the server instance has been destroyed, this method does nothing.
*
* @param room - The room name to publish the message to. All sockets that have joined this
* room (including the global broadcast room) will receive the message.
* @param message - The raw data to send. Accepts a `string` (sent as a UTF-8 text frame) or
* an `ArrayBuffer` / `Buffer` (sent as a binary frame).
* @param isBinary - Optional. If `true`, forces the message to be sent as a binary WebSocket
* frame. If `false` or omitted, the frame type is inferred from the type of
* `message` (`string` → text, `ArrayBuffer`/`Buffer` → binary).
* @param compress - Optional. If `true`, the message will be compressed using the WebSocket
* permessage-deflate extension (if negotiated with the clients).
*
* @example
* // Broadcast a JSON string to the "lobby" room
* io.rooms.publishRaw("lobby", JSON.stringify({ type: "announcement", text: "Server restart in 5m" }));
*
* @example
* // Broadcast pre-encoded MessagePack data to the "lobby" room
* const packed = msgpack.encode({ event: "system", status: "ok" });
* io.rooms.publishRaw("lobby", packed, true);
*
* @example
* // Send compressed binary data
* const buffer = new Uint8Array([1, 2, 3]);
* io.rooms.publishRaw("updates", buffer, true, true);
*/
publishRaw: (room: string, message: ServerOutgoingData, isBinary?: boolean, compress?: boolean) => this;
/**
* Emit a typed event to a specific room (server-side publish).
*
* @typeParam R - Room name (must be a key in `TEvents['emitRoom']`).
* @typeParam E - Event name.
* @typeParam D - Event data type.
*
* @example
* io.rooms.emit('chat', 'message', { text: 'Hello everyone' });
*/
emit: <R extends StringKeys<TEvents["emitRoom"]>, E extends StringNumberKeys<NonNullable<TEvents["emitRoom"]>[R]>, D extends NonNullable<TEvents["emitRoom"]>[R][E]>(room: R, event: E, data: D) => this;
/** Register a room event middleware. */
on: <R extends StringKeys<TEvents["listenRoom"]>, E extends StringNumberKeys<NonNullable<TEvents["listenRoom"]>[R]>, D extends NonNullable<TEvents["listenRoom"]>[R][E]>(room: R, event: E, callback: RoomEventMiddleware<TEvents, SD, D>) => this;
/** Remove a room event middleware. */
off: <R extends StringKeys<TEvents["listenRoom"]>, E extends StringNumberKeys<NonNullable<TEvents["listenRoom"]>[R]>, D extends NonNullable<TEvents["listenRoom"]>[R][E]>(room: R, event?: E, callback?: RoomEventMiddleware<TEvents, SD, D>) => this;
/** Register a one-time room event middleware. */
once: <R extends StringKeys<TEvents["listenRoom"]>, E extends StringNumberKeys<NonNullable<TEvents["listenRoom"]>[R]>, D extends NonNullable<TEvents["listenRoom"]>[R][E]>(room: R, event: E, callback: RoomEventMiddleware<TEvents, SD, D>) => this;
/** Lifecycle hooks for room join/leave (single rooms). */
lifecycle: IRoomsLifecycleServer<TEvents, SD>;
/** Bulk operations for multiple rooms. */
bulk: IRoomsBulkServer<TEvents, SD>;
}
/**
* Public API of a ByteSocket server instance.
*
* Manages WebSocket connections, rooms, middleware, and event routing.
* The implementation class {@link ByteSocket} should `implement` this interface.
*
* @typeParam TEvents - Event map (extends `SocketEvents`) defining the shape of
* all emit/listen events (global and room‑scoped).
* @typeParam SD - Socket data type that extends `SocketData`.
*/
interface IByteSocket<TEvents extends SocketEvents = SocketEvents, SD extends SocketData = SocketData, UpgradeCallback extends AnyCallback = AnyCallback> extends IByteSocketBase {
/**
* Lifecycle event listeners for connection, authentication, and errors.
*
* @example
* io.lifecycle.onOpen((socket) => console.log('Connected!'));
* io.lifecycle.onAuthError((socket, ctx) => console.error('Auth failed', ctx.error));
* io.lifecycle.onClose((socket, code, msg) => console.log('Closed', code));
*/
readonly lifecycle: ILifecycleServer<TEvents, SD, UpgradeCallback>;
/**
* Room management, room-scoped event emission, and room lifecycle hooks.
*
* @example
* io.rooms.emit('lobby', 'announcement', { text: 'Welcome!' });
* io.rooms.on('chat', 'message', (socket, data, next) => { ... });
* io.rooms.lifecycle.onJoin((socket, room, next) => {
* if (room === 'admin') next(new Error('Not allowed'));
* else next();
* });
*/
readonly rooms: IRoomsServer<TEvents, SD>;
/**
* Map of all currently connected sockets, keyed by socket ID.
*
* **Do not modify this map directly** - it is managed internally.
*
* @example
* for (const [id, socket] of io.sockets) {
* socket.emit('ping', undefined);
* }
*/
readonly sockets: Map<string, ISocket<TEvents, SD>>;
/**
* Indicates whether the server instance has been permanently destroyed.
*
* Once `true`, the instance cannot be reused; all connections have been closed and
* internal resources released. Use {@link destroy} to initiate shutdown.
*
* @example
* if (io.destroyed) {
* console.log('Server is shut down');
* }
*/
readonly destroyed: boolean;
/**
* Emit a global event to all connected sockets.
*
* @typeParam E - Event name (must be a key in `TEvents['emit']`).
* @typeParam D - Event data type.
*
* @example io.emit('userJoined', { userId: '123' });
*/
emit<E extends StringNumberKeys<TEvents["emit"]>, D extends NonNullable<TEvents["emit"]>[E]>(event: E, data: D): this;
/**
* Register a permanent listener for global events.
*
* @typeParam E - Event name (must be a key in `TEvents['listen']`).
*
* @example io.on('userJoined', (socket, data) => { console.log(data.userId); });
*/
on<E extends StringNumberKeys<TEvents["listen"]>, D extends NonNullable<TEvents["listen"]>[E]>(event: E, callback: EventCallback<TEvents, SD, D>): this;
/**
* Remove a listener for global events.
* If no callback is provided, **all** listeners for that event are removed.
*
* @example io.off('userJoined', myCallback);
*/
off<E extends StringNumberKeys<TEvents["listen"]>, D extends NonNullable<TEvents["listen"]>[E]>(event: E, callback?: EventCallback<TEvents, SD, D>): this;
/**
* Register a one-time listener for a global event.
* The callback is removed after the first invocation.
*
* @example io.once('userJoined', (socket, data) => { console.log('First join'); });
*/
once<E extends StringNumberKeys<TEvents["listen"]>, D extends NonNullable<TEvents["listen"]>[E]>(event: E, callback: EventCallback<TEvents, SD, D>): this;
/**
* Register a global middleware function.
* Middleware runs **before** any user message is processed.
*
* @example
* io.use((socket, ctx, next) => {
* console.log('Message received:', ctx);
* next();
* });
*/
use(fn: Middleware<TEvents, SD>): this;
attach(server: unknown, path: string): this;
destroy(): void;
}
//#endregion
//#region src/byte-socket-server-base.d.ts
type RequiredOptions = "middlewareTimeout" | "roomMiddlewareTimeout" | "authTimeout" | "broadcastRoom" | "onMiddlewareError" | "onMiddlewareTimeout" | "idleTimeout" | "sendPingsAutomatically";
declare abstract class ByteSocketServerBase<TEvents extends SocketEvents = SocketEvents, SD extends SocketData = SocketData, UpgradeCallback extends AnyCallback = AnyCallback> extends ByteSocketBase implements IByteSocket<TEvents, SD, UpgradeCallback> {
#private;
readonly lifecycle: ILifecycleServer<TEvents, SD, UpgradeCallback>;
readonly rooms: IRoomsServer<TEvents, SD>;
readonly sockets: Map<string, ISocket<TEvents, SD>>;
protected options: Omit<ByteSocketOptionsBase<TEvents, SD>, RequiredOptions | "debug" | "serialization" | "msgpackrOptions"> & Pick<Required<ByteSocketOptionsBase<TEvents, SD>>, RequiredOptions>;
constructor(options?: ByteSocketOptionsBase<TEvents, SD>);
abstract attach(server: unknown, path: string): this;
abstract destroy(): void;
protected abstract publishRaw(room: string, message: ServerOutgoingData, isBinary?: boolean, compress?: boolean): typeof this.rooms;
protected _destroy(): void;
emit<E extends StringNumberKeys<TEvents["emit"]>, D extends NonNullable<TEvents["emit"]>[E]>(event: E, data: D): this;
on<E extends StringNumberKeys<TEvents["listen"]>, D extends NonNullable<TEvents["listen"]>[E]>(event: E, callback: EventCallback<TEvents, SD, D>): this;
off<E extends StringNumberKeys<TEvents["listen"]>, D extends NonNullable<TEvents["listen"]>[E]>(event: E, callback?: EventCallback<TEvents, SD, D>): this;
once<E extends StringNumberKeys<TEvents["listen"]>, D extends NonNullable<TEvents["listen"]>[E]>(event: E, callback: EventCallback<TEvents, SD, D>): this;
use(fn: Middleware<TEvents, SD>): this;
get destroyed(): boolean;
protected message(socket: ISocket<TEvents, SD>, message: ServerIncomingData, isBinary: boolean): void;
protected close(socket: ISocket<TEvents, SD>, code: number, reason: Buffer | ArrayBuffer): void;
protected _runSyncHooks<Args extends Array<unknown>>(callbackSet: Set<AnyCallback> | undefined, args: Args, next: MiddlewareNext): void;
}
//#endregion
export { RoomEventMiddleware as _, IRoomsBulkServer as a, SocketData as b, ISocket as c, AuthCallback as d, AuthFunction as f, MiddlewareNext as g, Middleware as h, IRoomsBulkLifecycleServer as i, ISocketRooms as l, EventCallback as m, IByteSocket as n, IRoomsLifecycleServer as o, ByteSocketOptionsBase as p, ILifecycleServer as r, IRoomsServer as s, ByteSocketServerBase as t, ISocketRoomsBulk as u, ServerIncomingData as v, ServerOutgoingData as y };
//# sourceMappingURL=byte-socket-server-base-DFXqLJh0.d.ts.map
{"version":3,"file":"byte-socket-server-base-DFXqLJh0.d.ts","names":[],"sources":["../src/types.ts","../src/interfaces.ts","../src/byte-socket-server-base.ts"],"mappings":"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"}

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display